广告
返回顶部
首页 > 资讯 > 后端开发 > JAVA >使用mybatisPlus的queryWrapper进行子查询(以及传统xml方式做leftjoin)
  • 337
分享到

使用mybatisPlus的queryWrapper进行子查询(以及传统xml方式做leftjoin)

xmlmybatisjava 2023-09-04 12:09:18 337人浏览 八月长安
摘要

像多对多的数据表关系,比如检查套餐包含检查组,检查组包含检查项,我要想做一个setmeal对象包含groupList,而gropu有itemList,写mybatis的sql怎么写,而用mybatisPlus在java代码里应该怎么写 对于

像多对多的数据表关系,比如检查套餐包含检查组,检查组包含检查项,我要想做一个setmeal对象包含groupList,而gropu有itemList,写mybatissql怎么写,而用mybatisPlus在java代码里应该怎么写

对于多对多的数据表关系,在 MyBatis 中,通常会使用三张表来表示。以你提到的检查套餐包含检查组、检查组包含检查项为例,我们可以使用如下三张表来表示:

检查套餐表:t_setmeal,包含检查套餐的基本信息,如套餐名称、价格等等。
2. 检查组表:t_checkgroup,用于表示一个检查套餐中的一个检查组,一个套餐可以对应多个检查组。
3. 检查项表:t_checkitem,用于表示一个检查组中的一个检查项,一个检查组可以对应多个检查项。

下面分别介绍在 MyBatis 和 MyBatis-Plus 中,如何写 SQL 语句来查询检查套餐及其包含的检查组和检查项信息。

## 在 MyBatis 中实现

### 查询检查套餐及其包含的检查组和检查项```xml

  SELECT s.id, s.name, s.code, s.helpCode, s.sex, s.age, s.price, s.remark, s.attention, s.img,  g.id AS groupId, g.name AS groupName,  i.id AS itemId, i.name AS itemName  FROM t_setmeal s  LEFT JOIN t_setmeal_checkgroup sc ON s.id = sc.setmeal_id  LEFT JOIN t_checkgroup g ON sc.checkgroup_id = g.id  LEFT JOIN t_checkgroup_checkitem gi ON g.id = gi.checkgroup_id  LEFT JOIN t_checkitem i ON gi.checkitem_id = i.id  WHERE s.id = #{id}                                                    


```

上面的 SQL 语句使用了 JOIN 多张表,通过 LEFT JOIN 的方式来查询出检查套餐、检查组和检查项之间的关系。其中 resultMap 定义了映射结果,包含了检查套餐、检查组和检查项的信息,并通过 collection 标签来定义了集合类型的属性,把检查组和检查项映射到检查套餐中。

## 在 MyBatis-Plus 中实现

MyBatis-Plus 提供了比 MyBatis 更加简便的使用方式,可以通过实体对象直接进行 CRUD 操作,无需手写 SQL。以下简述如何通过 MyBatis-Plus 实现上面所述的功能。

### 查询检查套餐及其包含的检查组和检查项

为了方便操作,我们需要创建与实体类对应的 Mapper 接口和 Service 接口,并继承 MyBatis-Plus 提供的基类。以下是针对 t_setmeal 表的代码示例:```java

public interface SetmealMapper extends BaseMapper {}public interface SetmealService extends IService {    Setmeal findSetmealById(Long id);}@Servicepublic class SetmealServiceImpl extends ServiceImpl implements SetmealService {    @Override    public Setmeal findSetmealById(Long id) {        Setmeal setmeal = baseMapper.selectById(id);        List groupList = baseMapper.findGroupListBySetmealId(id);        for (CheckGroup group : groupList) {            List checkItemList = baseMapper.findItemListByGroupId(group.getId());            group.setItemList(checkItemList);        }        setmeal.setGroupList(groupList);        return setmeal;    }}


```

在上面的代码中,我们利用了 MyBatis-Plus 提供的 BaseMapper 接口和 ServiceImpl 类,简便地实现了 t_setmeal 表的 CRUD 操作,并且通过自定义方法 findSetmealById 来查询检查套餐及其包含的检查组和检查项信息。findSetmealById 方法中使用了两个自定义方法 findGroupListBySetmealId 和 findItemListByGroupId,分别查询检查套餐包含的检查组和检查组包含的检查项信息。

关于如何实现这两个自定义方法,以下是 MyBatis XML Mapper 的代码示例:```xml

    SELECT i.*    FROM t_checkgroup_checkitem gi    LEFT JOIN t_checkitem i ON gi.checkitem_id = i.id    WHERE gi.checkgroup_id = #{id,jdbcType=INTEGER}


```

上面的自定义方法使用了两个 SQL 语句,分别查询检查组和检查项的信息,并通过 resultMap 定义了映射结果。

最后,我们通过调用 SetmealService 中的 findSetmealById 方法来查询检查套餐及其包含的检查组和检查项信息。MyBatis-Plus 会自动进行对象的映射操作,将查询结果映射成对应的实体类对象。

好的,以下是使用 MyBatis-Plus 实现的 `findSetmealById` 方法:```java

@Servicepublic class SetmealServiceImpl extends ServiceImpl implements SetmealService {    @Autowired    private CheckGroupMapper checkGroupMapper;        @Autowired    private CheckItemMapper checkItemMapper;        @Override    public Setmeal findSetmealById(Long id) {        Setmeal setmeal = this.getById(id);                // 查询所有关联的检查组对象        List groupList = checkGroupMapper.selectList(new QueryWrapper().inSql("id", "select checkgroup_id from t_setmeal_checkgroup where setmeal_id = "+id));        for (CheckGroup group : groupList) {            // 查询所有关联的检查项对象            List itemList = checkItemMapper.selectList(new QueryWrapper().inSql("id", "select checkitem_id from t_checkgroup_checkitem where checkgroup_id = "+group.getId()));            group.setItemList(itemList);        }        setmeal.setGroupList(groupList);                return setmeal;    }}


```

在上述代码中,我们通过 `this.getById(id)` 方法来查询指定 ID 的检查套餐对象 `setmeal`。然后,我们通过 `checkGroupMapper.selectList` 方法,根据检查套餐与检查组之间的关系表(t_setmeal_checkgroup) 查询所有关联的检查组对象 `groupList`,并通过循环遍历每个检查组对象,再通过 `checkItemMapper.selectList` 方法,根据检查组与检查项之间的关系表(t_checkgroup_checkitem)查询所有关联的检查项对象,然后将检查项列表设置到检查组对象中,最后将检查组列表设置到检查套餐对象中,并返回它。

需要注意的是,在查询检查组和检查项的时候,我们使用了 `inSql` 方法,这是因为我们需要查询所有符合条件的对象,而不是只查询一个,而只使用 `eq` 等简单条件查询方法是无法实现的。

另外,需要在 `SetmealServiceImpl` 类中注入 `CheckGroupMapper` 和 `CheckItemMapper` 接口的实现类,这两个 Mapper 接口用于操作检查组表和检查项表。

如果要使用 MyBatis 实现以上代码逻辑,可以参考我之前回答你的问题时的答案。

好的,那么这里是使用 LambdaQueryWrapper 重写上述 `findSetmealById` 方法的示例代码:```java

@Servicepublic class SetmealServiceImpl extends ServiceImpl implements SetmealService {    @Autowired    private CheckGroupMapper checkGroupMapper;    @Autowired    private CheckItemMapper checkItemMapper;    @Override    public Setmeal findSetmealById(Long id) {        Setmeal setmeal = this.getById(id);        // 使用 LambdaQueryWrapper 查询所有关联的检查组对象        List groupList = checkGroupMapper.selectList(new LambdaQueryWrapper()                .inSql(CheckGroup::getId, "select checkgroup_id from t_setmeal_checkgroup where setmeal_id = " + id));        // 遍历所有关联的检查组对象并查询所有关联的检查项对象        groupList.forEach(group -> {            List itemList = checkItemMapper.selectList(new LambdaQueryWrapper()                    .inSql(CheckItem::getId, "select checkitem_id from t_checkgroup_checkitem where checkgroup_id = " + group.getId()));            group.setItemList(itemList);        });        setmeal.setGroupList(groupList);        return setmeal;    }}


```

在上述代码中,我们在查询检查组和检查项时使用了 LambdaQueryWrapper。具体来说,我们使用 `inSql` 方法来实现子查询,使用 `LambdaQueryWrapper::inSql` 方法可以避免手写 SQL,使代码更加简洁易读。

另外,需要注意的是,在遍历所有关联的检查组对象时,我们使用了 Lambda 表达式进行函数式编程。lambda 表达式可以使代码更加简洁,易于维护。

需要提醒的是,要使用 LambdaQueryWrapper,需要在项目中引入 MyBatis-Plus 的 Lambda 模块。

```xml

    com.baomidou    mybatis-plus-extension    ${mybatis-plus.version}


```

是的,`inSql()`是MyBatis-Plus中用于实现子查询的api之一。它允许我们嵌套一个子查询,将子查询的结果集作为查询条件之一,从而实现更加灵活和复杂的 SQL 查询。

使用 `inSql()` 时,我们需要先编写子查询语句,将结果集映射到某个字段或实体类中,再将子查询语句作为参数传递给 `inSql()` 方法中。例如:

```java

QueryWrapper wrapper = new QueryWrapper<>();wrapper.inSql("id", "select id from role where role_name like '管理员%'");List userList = userMapper.selectList(wrapper);


```

上述代码中,我们使用 `inSql()` 方法将一个子查询语句嵌套到主查询中。该子查询语句通过 `select id from role where role_name like '管理员%'` 获得一组角色ID,这些角色ID会作为过滤条件传递给 `inSql()` 方法中的第二个参数(即 `id` 字段)。该查询语句的意思是,查询角色名称以“管理员”开头的角色ID。由于 `inSql()` 方法本身不支持参数绑定,我们需要将子查询语句中的参数硬编码到语句中。

值得一提的是,MyBatis-Plus 中还有其他用于实现子查询的 API,如 `apply()`和`exists()`等方法。这些 API 均可用于构建复杂的 SQL 查询,并能帮助我们提升查询效率和减少数据库压力。

来源地址:https://blog.csdn.net/weixin_42759398/article/details/130498273

--结束END--

本文标题: 使用mybatisPlus的queryWrapper进行子查询(以及传统xml方式做leftjoin)

本文链接: https://www.lsjlt.com/news/393517.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作