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

这篇具有很好参考价值的文章主要介绍了使用mybatisPlus的queryWrapper进行子查询(以及传统xml方式做leftjoin)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

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

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

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

## 在 MyBatis 中实现

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

<select id="findSetmealById" resultMap="setmealResultMap">
  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}
</select>

<resultMap id="setmealResultMap" type="Setmeal">
  <id property="id" column="id"/>
  <result property="name" column="name"/>
  <result property="code" column="code"/>
  <result property="helpCode" column="helpCode"/>
  <result property="sex" column="sex"/>
  <result property="age" column="age"/>
  <result property="price" column="price"/>
  <result property="remark" column="remark"/>
  <result property="attention" column="attention"/>
  <result property="img" column="img"/>
  <collection property="groupList" ofType="CheckGroup">
    <id property="id" column="groupId" />
    <result property="name" column="groupName" />
    <collection property="itemList" ofType="CheckItem">
      <id property="id" column="itemId" />
      <result property="name" column="itemName" />
    </collection>
  </collection>
</resultMap>


```

上面的 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<Setmeal> {
}

public interface SetmealService extends IService<Setmeal> {
    Setmeal findSetmealById(Long id);
}

@Service
public class SetmealServiceImpl extends ServiceImpl<SetmealMapper, Setmeal> implements SetmealService {

    @Override
    public Setmeal findSetmealById(Long id) {
        Setmeal setmeal = baseMapper.selectById(id);
        List<CheckGroup> groupList = baseMapper.findGroupListBySetmealId(id);
        for (CheckGroup group : groupList) {
            List<CheckItem> 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 id="findGroupListBySetmealId" resultMap="BaseResultMap">
    SELECT g.*
    FROM t_setmeal_checkgroup sc
    LEFT JOIN t_checkgroup g ON sc.checkgroup_id = g.id
    WHERE sc.setmeal_id = #{id,jdbcType=INTEGER}
</select>

<select id="findItemListByGroupId" resultMap="BaseResultMap">
    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}
</select>


```

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

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

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

@Service
public class SetmealServiceImpl extends ServiceImpl<SetmealMapper, Setmeal> implements SetmealService {

    @Autowired
    private CheckGroupMapper checkGroupMapper;
    
    @Autowired
    private CheckItemMapper checkItemMapper;
    
    @Override
    public Setmeal findSetmealById(Long id) {
        Setmeal setmeal = this.getById(id);
        
        // 查询所有关联的检查组对象
        List<CheckGroup> groupList = checkGroupMapper.selectList(new QueryWrapper<CheckGroup>().inSql("id", "select checkgroup_id from t_setmeal_checkgroup where setmeal_id = "+id));
        for (CheckGroup group : groupList) {
            // 查询所有关联的检查项对象
            List<CheckItem> itemList = checkItemMapper.selectList(new QueryWrapper<CheckItem>().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

@Service
public class SetmealServiceImpl extends ServiceImpl<SetmealMapper, Setmeal> implements SetmealService {

    @Autowired
    private CheckGroupMapper checkGroupMapper;

    @Autowired
    private CheckItemMapper checkItemMapper;

    @Override
    public Setmeal findSetmealById(Long id) {
        Setmeal setmeal = this.getById(id);

        // 使用 LambdaQueryWrapper 查询所有关联的检查组对象
        List<CheckGroup> groupList = checkGroupMapper.selectList(new LambdaQueryWrapper<CheckGroup>()
                .inSql(CheckGroup::getId, "select checkgroup_id from t_setmeal_checkgroup where setmeal_id = " + id));

        // 遍历所有关联的检查组对象并查询所有关联的检查项对象
        groupList.forEach(group -> {
            List<CheckItem> itemList = checkItemMapper.selectList(new LambdaQueryWrapper<CheckItem>()
                    .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

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-extension</artifactId>
    <version>${mybatis-plus.version}</version>
</dependency>


```

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

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

```java

QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.inSql("id", "select id from role where role_name like '管理员%'");
List<User> 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://www.toymoban.com/news/detail-496733.html

到了这里,关于使用mybatisPlus的queryWrapper进行子查询(以及传统xml方式做leftjoin)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Mybatis-plus动态条件查询QueryWrapper的使用

    queryWrapper是mybatis plus中实现查询的对象封装操作类,可以封装sql对象,包括where条件,order by排序,select哪些字段等等,他的层级关系如下图: 2.1-案例一:根据name模糊查看未删除的用户列表信息 过滤条件: queryWrapper实现: 2.2-案例二:查看姓李的并且邮箱不为空的用户列表

    2024年02月14日
    浏览(38)
  • 【MybatisPlus】MP的分页查询、多条件查询以及查询过程中解决null的空值判定

    MP这样一款强大的持久层框架处理起来复杂的SQL来也是得心应手,效率极高,快快与我一同领略Plus的独特魅力吧 1.调用方法传入参数获取返回值 创建IPage分页对象,设置分页参数,1为当前页码,3为每页显示的记录数,执行分页查询并获取其结果 2.设置分页拦截器 将MP提供的分页

    2024年01月17日
    浏览(29)
  • Spring Boot学习随笔- 集成MyBatis-Plus(二)条件查询QueryWrapper、聚合函数的使用、Lambda条件查询

    学习视频:【编程不良人】Mybatis-Plus整合SpringBoot实战教程,提高的你开发效率,后端人员必备! 普通查询 条件构造器查询 【重要】 AbstractWrapper  是 MyBatis Plus 中的一个抽象类,用于构建 SQL 查询条件。定义了泛型  T 、 C  和  Children 。其中, T  表示实体类的类型, C  表示查

    2024年02月04日
    浏览(44)
  • 关于MyBatisPlus框架下出现xml里面定义的方法无法被正确识别以及提示调用mysql存储过程时参数无效的问题

    网上很多解决方法都是查看函数名是否一致、命名空间等,但还有一种可能是你调用接口的模块本身的resource文件夹下就有一个含有xml的mapper文件夹,而这个文件夹里面不含有方法A的sql实现,如下图: 导致程序只在这个mapper里面找A的sql实现,那肯定会提示没有找到。 除了检

    2024年02月09日
    浏览(40)
  • Mybatis-Plus高级查询LambdaQueryWrapper&QueryWrapper

    目录 前言 Wrapper 查询构造器 查询条件 前期准备 查询条件 allEq eq ne gt ge lt le between,notBetween like,notLike likeLeft likeRight isNull 空值查询 isNotNull 非空值查询 in notIn inSql、notInSql groupBy orderBy、orderByAsc、orderByDesc or、and 解决方法 last exists、notExists 总结 附加MySQL语句执行顺序 我刚刚毕

    2024年02月04日
    浏览(52)
  • SpringBoot整合Druid、Mybatis、MybatisPlus以及MybatisPlus的使用

    1)引入jar包 2)在application.yml中 注意: initialization-mode: always 第一次用过之后注释掉,或者将其改成never 3).启动项目,访问:http://127.0.0.1:8080/druid/          用户名:admin/密码:123456(在配置文件中有) ps:还记得mybatis中的sqlSessionFactory要传入一个dataSource吗?所以我们先学习

    2024年02月12日
    浏览(27)
  • QueryWrapper构建复杂的SQL-循环添加条件、联表查询

    QueryWrapper是MyBatis-Plus提供的一个查询构建器,用于构建复杂的SQL查询语句。QueryWrapper可以用于添加条件、排序、分页等操作。 循环添加条件 在QueryWrapper中,可以使用andWhere和orWhere方法来添加多个条件,从而实现循环添加条件。 下面是一个示例代码,演示如何使用QueryWrapper循

    2024年02月16日
    浏览(35)
  • sql中的时间范围查询【三种方式】以及Mapper.xml中遇到大于号小于号问题解决方案

    mapper注意事项 字符 转义字符 描述 gt; 大于 = gt;= 大于等于 lt; 小于 = lt;= 小于等于 \\\" quot; 双引号 ’ apos; 单引号 amp; and 遇到问题: 从数据库获取时间传到前端进行展示的时候,我们有时候可能无法得到一个满意的时间格式的时间日期,在数据库中显示的是正确的时间格式,获

    2024年02月10日
    浏览(34)
  • mysql数据库存数组类型数据,如何判断数组中是否包含某个值?使用mybatisplus查询。

    跟mybatisplus中.in()方法相反的函数 mybatisplus的in函数:查询的是数据库的某个属性的值是否在给定的集合中。这里我们讲的是一个值是否在数据库的某个属性数组中。 说明: 这是一张学生信息表,其中包含了学生曾经就读过的学校。现在我们要做的就是查询哪些学生就读过指

    2024年02月16日
    浏览(54)
  • 若依集成mybatisplus报错找不到xml

    引用:https://blog.csdn.net/qq_65080131/article/details/136677276 MybatisPlusAutoConfiguration 中可以知道,系统会自动配置SqlSessionFactory,,但是,当你有自定义的 SqlSessionFactory ,,就会出问题,,,, 若依中的 SqlSessionFactory 不是 MybatisSqlSessionFactory 所以需要,将SqlSessionFactory 换成, MybatisS

    2024年04月27日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包