最簡(jiǎn)單的MyBatis Plus的多表聯(lián)接、分頁查詢實(shí)現(xiàn)方法
一、前言
最近在加強(qiáng) ITAEM 團(tuán)隊(duì)的一個(gè) app 項(xiàng)目——學(xué)生教師學(xué)習(xí)交流平臺(tái)
人員組成:安卓 + 前端 + 后臺(tái)
后臺(tái) DAO 層借鑒了華工其他軟件開發(fā)團(tuán)隊(duì),使用了新穎強(qiáng)大的 MyBatisPlus
框架,里邊有一個(gè)類似百度貼吧的發(fā)帖子的功能:
而如果設(shè)計(jì)表,應(yīng)為
帖子表 t_post
- id
- title 標(biāo)題
- content 內(nèi)容
- xx
- user_id 用戶外鍵
用戶表 t_user
+ id
+ name 帖子發(fā)起者名字
+ xx
示例圖中紅色框中的內(nèi)容為 t_user
表的字段 name
,
而要實(shí)現(xiàn)上面顯示帖子,就要用到關(guān)聯(lián)查詢了,而且帖子很多,必須用分頁查詢,
那么,怎么通過 MyBatisPlus 來實(shí)現(xiàn)關(guān)聯(lián)、分頁查詢呢 ?很簡(jiǎn)單,往下看。
二、需求、數(shù)據(jù)庫表設(shè)計(jì)
這是個(gè)人 app 項(xiàng)目中 v1.0 版本的部分表。
需求:顯示帖子
要帖子基本內(nèi)容如時(shí)間、帖子內(nèi)容等,即 t_question
表的內(nèi)容全部要,
同時(shí)還要發(fā)帖子的人名字,即 t_student
的字段 name
三、代碼結(jié)構(gòu)
為了寫這篇文章,抽取了該 app 項(xiàng)目中的部分代碼,彼此相互關(guān)系如下圖
四、代碼實(shí)現(xiàn)
1、代碼已經(jīng)放到 github 上了,若對(duì)本文的代碼有疑問可以去 github 上查看詳情:
https://github.com/larger5/MyBatisPlus_page_tables.git
2、entity、mapper、service、controller
使用了 MyBatisPlus 的代碼生成器,自動(dòng)生成大部分基礎(chǔ)的代碼,操作方法見之前的文章:
在 SpringBoot 中引入 MyBatisPlus 之 常規(guī)操作
1.實(shí)體
① 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 = "學(xué)生外鍵id") @TableField("student_id") private Integer studentId; @ApiModelProperty(value = "問題內(nèi)容") private String content; @ApiModelProperty(value = "問題發(fā)布時(shí)間,發(fā)布的時(shí)候后臺(tái)自動(dòng)生成") 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 = "學(xué)生主鍵id") @TableId(value = "id", type = IdType.AUTO) private Integer id; @ApiModelProperty(value = "學(xué)生名稱") private String name; @ApiModelProperty(value = "學(xué)生密碼") private String password; @ApiModelProperty(value = "學(xué)生積分?jǐn)?shù)") private Integer points; @ApiModelProperty(value = "學(xué)生郵件地址") private String email; @ApiModelProperty(value = "學(xué)生手機(jī)號(hào)碼") private String phone; @ApiModelProperty(value = "學(xué)生學(xué)號(hào)") private String num; @ApiModelProperty(value = "學(xué)生真實(shí)姓名") @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 翻頁對(duì)象,可以作為 xml 參數(shù)直接使用,傳遞參數(shù) Page 即自動(dòng)分頁 * @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、關(guān)聯(lián)查詢 VO 對(duì)象
// import 省略 public class QuestionStudentVO implements Serializable { @ApiModelProperty(value = "問答主鍵id") @TableId(value = "id", type = IdType.AUTO) private Integer id; @ApiModelProperty(value = "學(xué)生外鍵id") @TableField("student_id") private Integer studentId; private String name; @ApiModelProperty(value = "問題內(nèi)容") private String content; @ApiModelProperty(value = "問題發(fā)布時(shí)間,發(fā)布的時(shí)候后臺(tái)自動(dòng)生成") private Date date; @ApiModelProperty(value = "問題懸賞的積分") private Integer value; // getter、setter 省略
五、測(cè)試接口
1、沒有關(guān)聯(lián)的分頁查詢接口
http://localhost/common/getAllQuestionByPage/1/2
① json 輸出
{ "code": 200, "data": { "total": 10, "size": 2, "current": 1, "records": [ { "id": 1, "studentId": 3, "content": "唐代,渝州城里,有一個(gè)性格開朗、樂觀的小伙子,名叫景天。", "date": 1534497561000, "value": 5 }, { "id": 2, "studentId": 1, "content": "雪見從小父母雙亡,由爺爺唐坤撫養(yǎng)成人。", "date": 1533201716000, "value": 20 } ], "pages": 5 } }
② sql 執(zhí)行
2、多表關(guān)聯(lián)、分頁查詢接口
http://localhost/common/getAllQuestionWithStudentByPage/1/2
① json 輸出
{ "code": 200, "data": { "total": 10, "size": 2, "current": 1, "records": [ { "id": 1, "studentId": 3, "name": "vv", "content": "唐代,渝州城里,有一個(gè)性格開朗、樂觀的小伙子,名叫景天。", "date": 1534497561000, "value": 5 }, { "id": 2, "studentId": 1, "name": "cun", "content": "雪見從小父母雙亡,由爺爺唐坤撫養(yǎng)成人。", "date": 1533201716000, "value": 20 } ], "pages": 5 } }
② sql 執(zhí)行
六、小結(jié)
寫本文的原因:
①網(wǎng)上有做法不合時(shí)宜的文章(自定義page類、配置版)②官方文檔使用的是配置版的,筆者采用注解版的
MyBatis 配置版 | MyBatis 注解版 |
---|---|
① 動(dòng)態(tài) sql 靈活、② xml 格式的 sql,可拓展性好 | ① 少一個(gè)設(shè)置,少一個(gè)錯(cuò)誤爆發(fā)點(diǎn)、② 代碼清晰優(yōu)雅 |
當(dāng)然,智者見智仁者見仁
參考資料:
MyBatisPlus 官方文檔:分頁插件:方式一 、傳參區(qū)分模式【推薦】
到此這篇關(guān)于最簡(jiǎn)單的MyBatis Plus的多表聯(lián)接、分頁查詢實(shí)現(xiàn)方法的文章就介紹到這了,更多相關(guān)MyBatis Plus多表聯(lián)接、分頁查詢內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java實(shí)現(xiàn)自定義中文排序的方法機(jī)注意事項(xiàng)
在Java中,中文排序通常涉及到使用Collator類來處理字符串的比較,確保根據(jù)漢字的拼音順序進(jìn)行排序,本文給大家介紹了Java實(shí)現(xiàn)自定義中文排序的方法機(jī)注意事項(xiàng),并有相關(guān)的代碼示例供大家參考,需要的朋友可以參考下2024-10-10SpringBoot結(jié)合mockito測(cè)試實(shí)戰(zhàn)
與集成測(cè)試將系統(tǒng)作為一個(gè)整體測(cè)試不同,單元測(cè)試更應(yīng)該專注于某個(gè)類。所以當(dāng)被測(cè)試類與外部類有依賴的時(shí)候,尤其是與數(shù)據(jù)庫相關(guān)的這種費(fèi)時(shí)且有狀態(tài)的類,很難做單元測(cè)試。但好在可以通過“Mockito”這種仿真框架來模擬這些比較費(fèi)時(shí)的類,從而專注于測(cè)試某個(gè)類內(nèi)部的邏輯2022-11-11Java 自定義Spring框架與Spring IoC相關(guān)接口分析
Spring框架是由于軟件開發(fā)的復(fù)雜性而創(chuàng)建的。Spring使用的是基本的JavaBean來完成以前只可能由EJB完成的事情。然而,Spring的用途不僅僅限于服務(wù)器端的開發(fā)2021-10-10springboot中websocket簡(jiǎn)單實(shí)現(xiàn)
本文主要介紹了springboot中websocket簡(jiǎn)單實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-01-01Java線程通訊的實(shí)現(xiàn)方法總結(jié)
線程通訊指的是多個(gè)線程之間通過共享內(nèi)存或消息傳遞等方式來協(xié)調(diào)和同步它們的執(zhí)行,線程通訊的實(shí)現(xiàn)方式主要有以下兩種:共享內(nèi)存和消息傳遞,本文詳細(xì)介紹了Java線程是如何通訊的,感興趣的同學(xué)可以參考閱讀2023-05-05IDEA代碼規(guī)范&質(zhì)量檢查的實(shí)現(xiàn)
這篇文章主要介紹了IDEA代碼規(guī)范&質(zhì)量檢查的實(shí)現(xiàn),文中通過圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08