MybatisPlus多表连接查询一对多分页查询数据

一、序言

在日常一线开发过程中,多表连接查询不可或缺,基于MybatisPlus多表连接查询究竟该如何实现,本文将带你找到答案。

在多表连接查询中,既有查询单条记录的情况,又有列表查询,还有分页查询,这些需求与多表连接是什么关系,又该如何实现,这是本文讨论的中心内容。

二、实战编码

1、两个关联DO

部门DO

@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName(value = "tb_dept")
public class Dept {
    private static final long serialVersionUID = 1L;
    @TableId(type = IdType.AUTO)
    private Long deptId;
    private String deptName;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime gmtCreate;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime gmtModified;
    private String tel;
    
    public Dept(Dept dept) {
        if (Objects.nonNull(dept)) {
            this.deptId = dept.deptId;
            this.deptName = dept.deptName;
            this.gmtCreate = dept.gmtCreate;
            this.gmtModified = dept.gmtModified;
            this.tel = dept.tel;
        }
    }
}

用户DO

@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName(value = "tb_user")
public class User {
    private static final long serialVersionUID = 1L;
    private Integer age;
    private Long deptId;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime gmtCreate;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime gmtModified;
    @TableId(type = IdType.AUTO)
    private Long userId;
    private String userName;
    
    public User(User user) {
        if (Objects.nonNull(user)) {
            this.age = user.age;
            this.deptId = user.deptId;
            this.gmtCreate = user.gmtCreate;
            this.gmtModified = user.gmtModified;
            this.userId = user.userId;
            this.userName = user.userName;
        }
    }
}
2、部门VO
@Data
@NoArgsConstructor
@AllArgsConstructor
public class DeptVo extends Dept {
    private List<User> userList;
    /**
     * 实现部门DO 转 部门VO
     * @param dept
     */
    public DeptVo(Dept dept) {
        super(dept);
    }
}
3、普通编码查询数据
public IPage<DeptVo> selectDeptPage3() {
    LambdaQueryWrapper<Dept> wrapper = Wrappers.lambdaQuery(Dept.class);
    Page<Dept> deptPage = this.page(new Page<>(1, 3), wrapper);
    IPage<DeptVo> deptVoPage = EntityUtils.toPage(deptPage, DeptVo::new);
    // 完成userList字段属性注入
    Set<Long> deptIds = EntityUtils.toSet(deptVoPage.getRecords(), DeptVo::getDeptId);
    if (deptIds.size() > 0) {
        List<User> userList = userMapper.selectList(Wrappers.lambdaQuery(User.class)
                                                    .in(User::getDeptId, deptIds));
        Map<Long, List<User>> map = EntityUtils.groupBy(userList, User::getDeptId);
        for (DeptVo deptVo : deptVoPage.getRecords()) {
            deptVo.setUserList(map.get(deptVo.getDeptId()));
        }
    }
    return deptVoPage;
}
4、使用工具类查询数据

优化版 一行代码完成userList属性注入

/**
 * 优化版 一行代码完成userList属性注入
 */
@Override
public IPage<DeptVo> selectDeptPage4() {
    LambdaQueryWrapper<Dept> wrapper = Wrappers.lambdaQuery(Dept.class);
    Page<Dept> deptPage = this.page(new Page<>(1, 3), wrapper);
    IPage<DeptVo> deptVoPage = EntityUtils.toPage(deptPage, DeptVo::new);
    //  一行代码完成userList属性注入
    FieldInjectUtils.injectListField(deptVoPage, DeptVo::getDeptId, UserServiceImpl.class, User::getDeptId, DeptVo::getUserList);
    return deptVoPage;
}

需要指出的是FieldInjectUtils在工具包下

<dependency>
    <groupId>xin.altitude.cms</groupId>
    <artifactId>ucode-cms-common</artifactId>
    <version>1.5.9.2</version>
</dependency>

学习源码的朋友,源码直通车

5、演示数据
{
  "code": 200,
  "msg": "操作成功",
  "data": {
    "records": [
      {
        "deptId": "10",
        "deptName": "Java",
        "gmtCreate": "2020-10-30 11:48:19",
        "gmtModified": "2021-05-24 15:11:17",
        "tel": "88886666",
        "userList": [
          {
            "age": 12,
            "deptId": "10",
            "gmtCreate": null,
            "gmtModified": "2022-11-05 16:44:22",
            "userId": "1",
            "userName": "Jone"
          }
        ]
      },
      {
        "deptId": "11",
        "deptName": "Mysql",
        "gmtCreate": "2020-10-30 11:48:44",
        "gmtModified": "2021-05-24 15:11:20",
        "tel": "80802121",
        "userList": [
          {
            "age": 23,
            "deptId": "11",
            "gmtCreate": null,
            "gmtModified": "2022-11-05 16:44:24",
            "userId": "2",
            "userName": "Jack"
          },
          {
            "age": 21,
            "deptId": "11",
            "gmtCreate": "2022-11-05 16:09:42",
            "gmtModified": "2022-11-05 16:11:28",
            "userId": "5",
            "userName": "滴滴"
          }
        ]
      },
      {
        "deptId": "12",
        "deptName": "Tomcat",
        "gmtCreate": "2020-10-30 11:48:44",
        "gmtModified": "2021-05-24 15:11:23",
        "tel": "23231212",
        "userList": [
          {
            "age": 22,
            "deptId": "12",
            "gmtCreate": null,
            "gmtModified": "2022-11-05 16:44:27",
            "userId": "3",
            "userName": "Billie"
          },
          {
            "age": 12,
            "deptId": "12",
            "gmtCreate": "2021-06-05 19:22:46",
            "gmtModified": "2021-10-21 14:38:26",
            "userId": "4",
            "userName": "didi"
          },
          {
            "age": 18,
            "deptId": "12",
            "gmtCreate": "2022-11-05 16:10:48",
            "gmtModified": "2022-11-05 16:11:36",
            "userId": "6",
            "userName": "嗒嗒"
          }
        ]
      }
    ],
    "total": 4,
    "size": 3,
    "current": 1,
    "orders": [],
    "optimizeCountSql": true,
    "searchCount": true,
    "countId": null,
    "maxLimit": null,
    "pages": 2
  }
}

三、小结

本文完成了MybatisPlus一对多分页查询数据的开发需求,更多细节内容,视频直通车。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: MyBatis-Plus 提供了多种方式进行连表查询,这里介绍其中两种方式: 1. 使用 @TableField 注解进行连表查询 在实体类中使用 @TableField 注解标识外键字段,同时使用 @TableField(exist=false) 指定该字段为非数据库字段,然后在查询时使用 Wrapper 进行连表查询,例如: ```java // User 实体类 @Data public class User { private Long id; private String name; private Integer age; private String email; @TableField("dept_id") private Long deptId; // 外键字段,对应 Dept 表的 id } // Dept 实体类 @Data public class Dept { private Long id; private String name; } // 查询操作 QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.eq("user.id", 1); // 限定查询条件 wrapper.eq("dept.name", "IT"); // 连表查询条件 wrapper.select("user.*", "dept.name as dept_name"); // 查询结果字段 wrapper.leftJoin("dept", "user.dept_id = dept.id"); // 左连接查询 List<User> userList = userMapper.selectList(wrapper); ``` 2. 使用 LambdaWrapper 进行连表查询 LambdaWrapper 是 MyBatis-Plus 提供的一种函数式查询方式,可以更加直观地进行连表查询,例如: ```java // 查询操作 LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>(); wrapper.eq(User::getId, 1) // 限定查询条件 .eq(Dept::getName, "IT") // 连表查询条件 .select(User.class, info -> !info.getColumn().equals("dept_id")) // 查询结果字段 .leftJoin(Dept.class, User::getDeptId, Dept::getId); // 左连接查询 List<User> userList = userMapper.selectList(wrapper); ``` 以上两种方式都可以进行多表查询,只需要在查询条件和连接查询的表中添加相应的查询条件和连接条件即可。 ### 回答2: MyBatis-Plus是一款轻量级、功能强大的Java持久层框架,它在MyBatis的基础上进行了扩展,提供了更多便捷的特性。在MyBatis-Plus中进行连表查询,可以通过使用实体类的关联注解和条件构造器来实现。 首先,我们需要在每个涉及到外键的实体类中使用注解来建立关联,并在属性上指定对应的关联关系。比如使用@OneToOne、@OneToMany、@ManyToOne、@ManyToMany等注解来建立一对一、一对多、多对一、多对多的关系。 然后,我们可以使用MyBatis-Plus提供的条件构造器来构建复杂的查询条件。条件构造器提供了很多方法,比如eq、ne、ge、le、like等,可以方便地拼接查询条件。在连表查询中,我们可以通过条件构造器来指定关联查询的条件,比如使用eq方法来指定两个实体类的关联字段相等。 最后,使用MyBatis-Plus提供的查询方法,比如selectList、selectPage等来执行查询操作。在查询方法中,可以通过指定参数来传递条件构造器对象,从而实现连表查询操作。查询结果会返回一个包含所有查询数据的List或Page对象,可以根据需要进行处理和展示。 总结来说,MyBatis-Plus可以通过实体类的关联注解和条件构造器来实现连表查询。关联注解用于建立实体类之间的关联关系,条件构造器用于构建复杂的查询条件。使用MyBatis-Plus提供的查询方法可以执行查询操作,并获取查询结果进行处理。这样,我们就可以方便地进行连表查询操作了。 ### 回答3: MyBatis Plus是一种基于MyBatis框架的增强工具,它可以简化数据库操作。连接查询是在数据库中同时查询多个表的操作。在MyBatis Plus中,连接查询可以通过多种方式实现。 1. 注解方式:使用@TableName注解来指定实体类与数据库表的映射关系,使用@JoinTable注解来指定连接表的关联关系。然后使用@Select注解来编写连接查询的SQL语句。 2. XML配置方式:在MyBatis的mapper.xml文件中,使用<resultMap>来定义结果映射关系,在<resultMap>中使用<association>或<collection>来定义连接查询的关联关系。然后在SQL语句中使用JOIN关键字来连接表。 3. Lambda表达式方式:使用lambda表达式可以更加简洁地实现连接查询。通过MyBatis Plus的Wrapper对象,可以使用lambda表达式来定义查询条件,并通过selectJoin方法进行连接查询。 无论是哪种方式,连接查询的关键是要理解好数据库表之间的关联关系,以及如何在SQL语句中使用JOIN关键字进行连接查询。另外,还要注意在查询结果中正确处理连接查询返回的重复数据,以及对查询结果进行分页处理等操作。 总结来说,通过MyBatis Plus实现连接查询,可以通过注解方式、XML配置方式和Lambda表达式方式来实现。根据具体的实际需求和个人喜好,选择合适的方式进行连接查询操作。连接查询对理解数据库的表关系和使用JOIN关键字有一定要求,需要在编写SQL语句时注意正确处理返回结果和分页操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值