最简单的MyBatis Plus的多表联接、分页查询实现方法

作者:IT小村 时间:2022-07-10 05:21:49 

一、前言

最近在加强 ITAEM 团队的一个 app 项目——学生教师学习交流平台
人员组成:安卓 + 前端 + 后台
后台 DAO 层借鉴了华工其他软件开发团队,使用了新颖强大的 MyBatisPlus 框架,里边有一个类似百度贴吧的发帖子的功能:

最简单的MyBatis Plus的多表联接、分页查询实现方法

而如果设计表,应为

帖子表 t_post
- id
- title 标题
- content 内容
- xx
- user_id 用户外键
用户表 t_user
+ id
+ name 帖子发起者名字
+ xx

示例图中红色框中的内容为 t_user 表的字段 name
而要实现上面显示帖子,就要用到关联查询了,而且帖子很多,必须用分页查询,

那么,怎么通过 MyBatisPlus 来实现关联、分页查询呢 ?很简单,往下看。

二、需求、数据库表设计

这是个人 app 项目中 v1.0 版本的部分表。

最简单的MyBatis Plus的多表联接、分页查询实现方法

需求:显示帖子

要帖子基本内容如时间、帖子内容等,即 t_question 表的内容全部要,

同时还要发帖子的人名字,即 t_student 的字段 name

三、代码结构

为了写这篇文章,抽取了该 app 项目中的部分代码,彼此相互关系如下图

最简单的MyBatis Plus的多表联接、分页查询实现方法

四、代码实现

1、代码已经放到 github 上了,若对本文的代码有疑问可以去 github 上查看详情:
https://github.com/larger5/MyBatisPlus_page_tables.git

2、entity、mapper、service、controller 使用了 MyBatisPlus 的代码生成器,自动生成大部分基础的代码,操作方法见之前的文章:
在 SpringBoot 中引入 MyBatisPlus 之 常规操作

1.实体

① Question


// import 省略

@TableName("t_question")
public class Question implements Serializable {

private static final long serialVersionUID = 1L;

@ApiModelProperty(value = "问答主键id")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;

@ApiModelProperty(value = "学生外键id")
@TableField("student_id")
private Integer studentId;

@ApiModelProperty(value = "问题内容")
private String content;

@ApiModelProperty(value = "问题发布时间,发布的时候后台自动生成")
private Date date;

@ApiModelProperty(value = "问题悬赏的积分")
private Integer value;

// getter、setter 省略
}

② Student


// import 省略

@TableName("t_student")
public class Student implements Serializable {

private static final long serialVersionUID = 1L;

@ApiModelProperty(value = "学生主键id")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;

@ApiModelProperty(value = "学生名称")
private String name;

@ApiModelProperty(value = "学生密码")
private String password;

@ApiModelProperty(value = "学生积分数")
private Integer points;

@ApiModelProperty(value = "学生邮件地址")
private String email;

@ApiModelProperty(value = "学生手机号码")
private String phone;

@ApiModelProperty(value = "学生学号")
private String num;

@ApiModelProperty(value = "学生真实姓名")
@TableField("true_name")
private String trueName;

// getter、setter 省略
}

2.mapper

① StudentMapper


// import 省略
public interface StudentMapper extends BaseMapper<Student> {
}

② QuestionMapper


// import 省略
public interface QuestionMapper extends BaseMapper<Question> {
/**
 *
 * @param page 翻页对象,可以作为 xml 参数直接使用,传递参数 Page 即自动分页
 * @return
 */
@Select("SELECT t_question.*,t_student.`name` FROM t_question,t_student WHERE t_question.student_id=t_student.id")
List<QuestionStudentVO> getQuestionStudent(Pagination page);

}

3、service

① StudentService


// import 省略
public interface StudentService extends IService<Student> {
}

② QuestionService


// import 省略
public interface QuestionService extends IService<Question> {

Page<QuestionStudentVO> getQuestionStudent(Page<QuestionStudentVO> page);

}

4、serviceImpl

① StudentServiceImpl


// import 省略
@Service
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements StudentService {

}

② QuestionServiceImpl


// 省略 import

@Service
public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> implements QuestionService {

@Override
public Page<QuestionStudentVO> getQuestionStudent(Page<QuestionStudentVO> page) {
 return page.setRecords(this.baseMapper.getQuestionStudent(page));
}

}

5、controller


// 省略 import

@RestController
@RequestMapping("/common")
@EnableSwagger2
public class CommonController {

@Autowired
QuestionService questionService;

@Autowired
StudentService studentService;

@GetMapping("/getAllQuestionByPage/{page}/{size}")
public Map<String, Object> getAllQuestionByPage(@PathVariable Integer page, @PathVariable Integer size) {
 Map<String, Object> map = new HashMap<>();
 Page<Question> questionPage = questionService.selectPage(new Page<>(page, size));
 if (questionPage.getRecords().size() == 0) {
  map.put("code", 400);
 } else {
  map.put("code", 200);
  map.put("data", questionPage);
 }
 return map;
}

@GetMapping("/getAllQuestionWithStudentByPage/{page}/{size}")
public Map<String, Object> getAllQuestionWithStudentByPage(@PathVariable Integer page, @PathVariable Integer size) {
 Map<String, Object> map = new HashMap<>();
 Page<QuestionStudentVO> questionStudent = questionService.getQuestionStudent(new Page<>(page, size));
 if (questionStudent.getRecords().size() == 0) {
  map.put("code", 400);
 } else {
  map.put("code", 200);
  map.put("data", questionStudent);
 }
 return map;
}

}

6、MyBatisPlus 配置


// 省略 import

@EnableTransactionManagement
@Configuration
@MapperScan("com.cun.app.mapper")
public class MybatisPlusConfig {

/**
 * 分页插件
 */
@Bean
public PaginationInterceptor paginationInterceptor() {
 return new PaginationInterceptor();
}

/**
 * 打印 sql
 */
@Bean
public PerformanceInterceptor performanceInterceptor() {
 PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
 //格式化sql语句
 Properties properties = new Properties();
 properties.setProperty("format", "true");
 performanceInterceptor.setProperties(properties);
 return performanceInterceptor;
}
}

7、关联查询 VO 对象


// import 省略

public class QuestionStudentVO implements Serializable {

@ApiModelProperty(value = "问答主键id")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;

@ApiModelProperty(value = "学生外键id")
@TableField("student_id")
private Integer studentId;

private String name;

@ApiModelProperty(value = "问题内容")
private String content;

@ApiModelProperty(value = "问题发布时间,发布的时候后台自动生成")
private Date date;

@ApiModelProperty(value = "问题悬赏的积分")
private Integer value;

// getter、setter 省略

五、测试接口

最简单的MyBatis Plus的多表联接、分页查询实现方法

1、没有关联的分页查询接口

http://localhost/common/getAllQuestionByPage/1/2

① json 输出


{
"code": 200,
"data": {
"total": 10,
"size": 2,
"current": 1,
"records": [
 {
 "id": 1,
 "studentId": 3,
 "content": "唐代,渝州城里,有一个性格开朗、乐观的小伙子,名叫景天。",
 "date": 1534497561000,
 "value": 5
 },
 {
 "id": 2,
 "studentId": 1,
 "content": "雪见从小父母双亡,由爷爷唐坤抚养成人。",
 "date": 1533201716000,
 "value": 20
 }
],
"pages": 5
}
}

② sql 执行

最简单的MyBatis Plus的多表联接、分页查询实现方法

2、多表关联、分页查询接口

http://localhost/common/getAllQuestionWithStudentByPage/1/2

① json 输出


{
"code": 200,
"data": {
"total": 10,
"size": 2,
"current": 1,
"records": [
 {
 "id": 1,
 "studentId": 3,
 "name": "vv",
 "content": "唐代,渝州城里,有一个性格开朗、乐观的小伙子,名叫景天。",
 "date": 1534497561000,
 "value": 5
 },
 {
 "id": 2,
 "studentId": 1,
 "name": "cun",
 "content": "雪见从小父母双亡,由爷爷唐坤抚养成人。",
 "date": 1533201716000,
 "value": 20
 }
],
"pages": 5
}
}

② sql 执行

最简单的MyBatis Plus的多表联接、分页查询实现方法

六、小结

写本文的原因:

①网上有做法不合时宜的文章(自定义page类、配置版)②官方文档使用的是配置版的,笔者采用注解版的


MyBatis 配置版MyBatis 注解版
① 动态 sql 灵活、② xml 格式的 sql,可拓展性好① 少一个设置,少一个错误爆发点、② 代码清晰优雅

当然,智者见智仁者见仁

参考资料:
MyBatisPlus 官方文档:分页插件:方式一 、传参区分模式【推荐】

来源:https://larger5.blog.csdn.net/article/details/82082819

标签:MyBatis,Plus,多表联接,分页查询
0
投稿

猜你喜欢

  • C#实现将窗体固定在显示器的左上角且不能移动的方法

    2022-03-04 18:34:17
  • C#通用邮件发送类分享

    2022-05-03 01:35:36
  • Kotlin 协程与挂起函数及suspend关键字深入理解

    2023-09-19 01:04:25
  • 老生常谈java中的fail-fast机制

    2022-01-27 15:31:50
  • Java集合ArrayList与LinkedList详解

    2022-11-11 12:14:31
  • JAVA包装类及自动封包解包实例代码

    2022-10-23 13:28:54
  • C# 将 Stream 保存到文件的方法

    2021-10-13 12:47:59
  • MyBatis实现物理分页的实例

    2023-03-13 04:21:45
  • Android开发之拖动条/滑动条控件、星级评分控件功能的实例代码

    2022-04-26 20:29:21
  • Java中this和super的区别及this能否调用到父类使用

    2023-01-05 12:03:13
  • C#生成单页静态页简单实例

    2022-01-22 20:00:57
  • SpringBoot内置tomcat启动原理详解

    2021-11-02 19:32:33
  • Android XRecyclerView实现多条目加载

    2021-10-15 07:32:21
  • Swing拆分窗格控件JSplitPane使用详解

    2022-11-14 21:13:48
  • Mybatis配置文件之动态SQL配置备忘录

    2023-11-21 00:13:02
  • eclipse连接不到genymotion问题的解决方案

    2022-09-05 23:26:16
  • Java并发的CAS原理与ABA问题的讲解

    2023-11-25 12:17:21
  • 如何将C语言代码转换为应用程序(也就是编译)

    2022-09-02 06:30:49
  • json格式数据分析工具PageElement类分享(仿Session写法)

    2023-09-16 16:04:32
  • Java集合Stream流操作的基本使用教程分享

    2023-09-01 01:05:03
  • asp之家 软件编程 m.aspxhome.com