一、序言

在日常一线开发过程中,多表连接查询不可或缺,基于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一对多分页查询数据的开发需求,更多细节内容,视频直通车。

MybatisPlus多表连接查询一对多分页查询数据的更多相关文章

  1. 【mysql】 mybatis实现 主从表 left join 1:n 一对多 分页查询 主表从表都有查询条件 【mybatis】count 统计+JSON查询

    mybatis实现 主从表 left join  1:n 一对多 分页查询   主表从表都有查询条件+count 需求: ======================================= ...

  2. 分页查询信息(使用jdbc连接mysql数据库实现分页查询任务)

             分页查询信息       使用jdbc连接mysql数据库实现分页查询任务 通过mysql数据库提供的分页机制,实现商品信息的分页查询功能,将查询到的信息显示到jsp页面上. 本项目 ...

  3. MybatisPlus多表连接查询

    一.序言 (一)背景内容 软件应用技术架构中DAO层最常见的选型组件为MyBatis,熟悉MyBatis的朋友都清楚,曾几何时MyBatis是多么的风光,使用XML文件解决了复杂的数据库访问的难题.时 ...

  4. 【mybatis】在mybatis分页查询时,主表对关联表 一对多 分页查询怎么实现

    现在有这样一个需求: 1.积分商品分页查询 2.一个积分商品会有多张商品图片在商品图片表  1:n的关系 这样在积分商品分页查询的时候,想要顺便把每个积分商品对应的商品图片信息也带出来 实现如下: 1 ...

  5. JPA分页查询与条件分页查询

    情有独钟的JPA 平时在写一些小项目时,比较喜欢引用 Spring Data Jpa,其实还是图他写代码快~在日常的开发工作中,分页列表查询基本是随处可见,下面一起看一下如何使用 jpa 进行多条件查 ...

  6. MySQL的分页查询及Oracle分页查询

    MySQL: Select ... from ...where ...order by...limit start,pageNum 例:比如从 取 个数据 , String sql = )*pageR ...

  7. Oracle 数据库分页查询与排序分页查询

    一.分页查询 原始查询语句 SELECT * FROM NASLE_WFSHH 修改为分页查询语句,加上 ROWNUM 列.此处为查询第 1 页,每页 9 条数据 SELECT * FROM ( SE ...

  8. DQL分组查询和DQL分页查询

    分组查询: 1.语法:group by 分组字段: 2.注意: 分组之后查询的字符按:分组字段.聚合函数 where 和having 的区别 where再分组前进行限定,如果不满足条件则不参与分组.h ...

  9. oracle 一对多数据分页查询筛选

    今天项目测试运行的时候,遇到了一个奇怪的问题,这个问题说起来按sql语法的话是没有错误的 但是呢按照我们的业务来做区分就有些逻辑上的错误了, 下面请听我慢慢道来,在数据库中有两个数据, 先来看下第一次 ...

  10. linq查询集合并分页展示数据

    private void Bind() { if (Request.QueryString["QuestionNo"] != null) { string QuestionNo = ...

随机推荐

  1. typora收费了,最后一个免费版提供下载

    typora收费了,在这里,博主提供最后一个免费版下载,地址如下,顺便把typora导入和导出word时需要的工具也一同提供.最看不惯免费用着别人的软件,还搞引流的垃圾网站和公众号.地址如下 http ...

  2. Beats:Beats 入门教程 (二)

  3. 6.使用nexus3配置yum私有仓库

    yum相较于rpm,能够更好地解决安装软件时的依赖包问题,使用yum安装更简单更方便.搭建本地YUM源服务器,可以避免升级安装软件时占用公网带宽:有了本地YUM源服务器,可以解决无法连接Interne ...

  4. 2. Fluentd事件的生命周期

    事件(Event)是Fluentd内部处理流程使用的数据结构,日志记录一旦进入Fluentd便被封装成一个event.Event由三部分组成:tag.time.record. tag: 标识事件的来源 ...

  5. 【前端必会】webpack loader 到底是什么

    概述 webpack的使用中我们会遇到各种各样的插件.loader. webpack的功力主要体现在能理解各个插件.loader的数量上.理解的越多功力越深 loader是什么呢? 背景 了解load ...

  6. 15. MongoDB系列之选择片键

    1. 片键类型 1.1 升序片键 升序片键通常类似于date或ObjectId--随着时间稳步增长的字段. 这种模式通常会使MongoDB更难保持块的平衡,因为所有的块都是由一个分片创建的. 1.2 ...

  7. 齐博x2模型里边钩子的创建与使用

    在模型里边的钩子创建与使用方法跟在控制器里边的钩子创建及使用方法是有所区别的在模型里边创建的钩子,你可以理解为执行一个函数,是无法调用模型里边的类的方法及属性的.比如系统文件\application\ ...

  8. etcd定时任务脚本执行失败

    etcd定时任务脚本执行失败 报错如下:etcdctl命令不存在 是因为在脚本中etcdctl命令没有写绝对路径,修改标记部分改成绝对路径 可以先获取路径然后改成绝对路径问题解决 which etcd ...

  9. 为什么CSS中的calc函数可能会不生效?

    前言 在早期如果想要对某一些样式进行动态计算,绝大多数的做法都是使用JavaScript来进行,当时的CSS在面对这种场景显得有点无能为力.但是,当CSS3中新增了calc函数时,面对这种场景,Jav ...

  10. Redis 先操作数据库和先删除缓存, 一致性分析

    初始状态: 数据库和缓存中v=10 第一种,先删除缓存在操作数据库: 线程1准备更新数据库的值v=20,先删除缓存, 此时线程2进来, 缓存未命中,查询数据库v=10, 写入缓存v=10, cpu回到 ...