SpringBoot系列(五):SpringBoot整合Mybatis實現(xiàn)多表關(guān)聯(lián)查詢
作者:
修羅debug
版權(quán)聲明:本文為博主原創(chuàng)文章,遵循 CC 4.0 by-sa 版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接和本聲明。
摘要:本文我們將繼續(xù)分享介紹Spring Boot在整合Mybatis開發(fā)企業(yè)級應用時其他典型的業(yè)務場景,即Mybatis是如何實現(xiàn)多表關(guān)聯(lián)查詢時將查詢結(jié)果集與對象進行映射的,主要的內(nèi)容包含“一對一的表關(guān)聯(lián)”和“一對多/多對多的表關(guān)聯(lián)”查詢。
內(nèi)容:在上一篇文章中,我們分享介紹了如何基于Spring Boot搭建的標準企業(yè)級項目整合第三方的持久層依賴Mybatis,并實現(xiàn)最基本的CRUD功能,此種CRUD估計大伙都明白這是只針對“單一的數(shù)據(jù)庫表”操作的。
而本文我們將趁熱打鐵,繼續(xù)分享介紹不一樣的內(nèi)容,即如何基于Mybatis實現(xiàn)“Java對象”與“多表關(guān)聯(lián)查詢結(jié)果集”的映射。
在開始代碼實戰(zhàn)之前,我們簡單的需要建立兩張數(shù)據(jù)庫表,分別是user用戶表、comment評論表,其對應的數(shù)據(jù)庫建表語句DDL如下所示:
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '名字',
`code` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '工號',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用戶信息表';
CREATE TABLE `comment` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`content` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '評論',
`user_id` int(11) DEFAULT NULL COMMENT '評論者id',
`article_id` int(11) DEFAULT NULL COMMENT '文章id',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='評論';
其中,在上一篇文章中建立的數(shù)據(jù)庫表
“article文章”的user_id即來源于user用戶表的主鍵id,而一篇文章會有很多評論,這些評論信息將存儲在comment評論表中,從而,我們可以看出,user與article數(shù)據(jù)表是平級的關(guān)系,而article與comment數(shù)據(jù)庫表則屬于一對多的關(guān)聯(lián)關(guān)系!
廢話不多講,下面就代碼實戰(zhàn)環(huán)節(jié):
一、數(shù)據(jù)庫表為一對一的平級關(guān)聯(lián)關(guān)系實戰(zhàn)(涉及user、article表)
(1)首先我們需要明確實戰(zhàn)的業(yè)務場景:“根據(jù)文章的主鍵id或者文章的詳情,在文章的詳情中除了需要顯示文章的具體信息之外,還需要顯示作者的相關(guān)信息”。
基于這樣的業(yè)務場景,首先我們需要將Sql寫好,如下所示為Mapper.xml對應的代碼:
<select id="selectById" resultType="com.debug.springboot.model.entity.Article">
SELECT
a.id,
a.title,
a.user_id,
b.name AS userName
FROM article AS a LEFT JOIN user AS b ON b.id = a.user_id
WHERE a.id = #{id}
</select>
在這里,我們采用的是“左關(guān)聯(lián)”的方式,在獲取文章詳情的同時,獲取該文章所屬的作者的相關(guān)信息!而為了能讓“Java對象”接收存儲查詢出來的屬于用戶層面的信息,我們需要在Article類中添加用戶相關(guān)的“字段信息”,如下所示(在這里我們提前將后文即將要介紹的在一對多映射時需要的comments字段建好了?。?nbsp;
@Data
public class Article {
private Integer id;
@NotBlank(message = "文章標題不能為空")
private String title;
@NotNull
private Integer userId;
//子查詢映射
private List<Comment> comments;
//作者名字
private String userName;
}
緊接著,當然是Controller的代碼啦:
//多表關(guān)聯(lián)-平級
@RequestMapping(value = "info/{id}")
public BaseResponse info(@PathVariable Integer id){
BaseResponse response=new BaseResponse(StatusCode.Success);
try {
response.setData(articleService.info(id));
}catch (Exception e){
response=new BaseResponse(StatusCode.Fail.getCode(),e.getMessage());
}
return response;
}
而Service的代碼邏輯也比較簡單,如下所示:
//詳情
@Override
public Article info(Integer id) throws Exception {
return articleMapper.selectById(id);
}
Mapper操作接口對應的方法定義如下所示:
Article selectById(@Param("id") Integer id);
最后,當然是將項目運行起來,然后采用瀏覽器或者postman進行自測訪問,廢話不多講,看圖:
查看該響應結(jié)果中userName字段的值,我們即可大膽的認為我們的寫法是沒毛病的!當然啦,如果需要顯示的用戶層面的字段過多,則可以將那些字段信息封裝成“實體類”,并在Article類中定義該類的對象實例即可!如果只是幾個字段,那就直接定義在Article里面即可!
二、數(shù)據(jù)庫表為一對多/多對多的平級關(guān)聯(lián)關(guān)系實戰(zhàn)
(1)對于“一對多的數(shù)據(jù)庫表關(guān)聯(lián)實戰(zhàn)”,在這里我們采用的是以“一篇文章article,將對應著多條評論記錄comment”為案例進行實戰(zhàn)。同樣的道理,首先我們直接看Mapper.xml中動態(tài)Sql的寫法:
<select id="list" resultMap="BaseResultInfoMap">
SELECT
a.*,
c.name AS userName,
b.id AS cId,
b.content AS comment,
b.user_id AS cUserId
FROM
article AS a
LEFT JOIN `comment` AS b ON b.article_id=a.id
LEFT JOIN user AS c ON c.id = a.user_id
ORDER BY a.id
</select>
在這里,我們采用的仍然是左關(guān)聯(lián)的方式進行表與表之間的關(guān)聯(lián)查詢,a.*代表的是文章的詳細信息,而b.id,b.content,b.user_id等字段信息代表的是評論表的信息,那最終如何體現(xiàn)出這兩個實體對象之間的“一對多關(guān)聯(lián)”關(guān)系呢? 很簡單,我們只需要做2個步驟:
A.第一是定義查詢的結(jié)果集映射,即BaseResultInfoMap,其完整的代碼定義如下所示:
<resultMap id="BaseResultInfoMap" type="com.debug.springboot.model.entity.Article" >
<id column="id" property="id" jdbcType="INTEGER" />
<result column="title" property="title" jdbcType="VARCHAR" />
<result column="user_id" property="userId" jdbcType="INTEGER" />
<collection property="comments" ofType="com.debug.springboot.model.entity.CommentInfo">
<result column="cId" property="cId" jdbcType="VARCHAR" />
<result column="comment" property="comment" jdbcType="VARCHAR" />
<result column="cUserId" property="cUserId" jdbcType="INTEGER" />
</collection>
</resultMap>
其主要是借助mybatis的collection標簽屬性以及ofType來實現(xiàn)!
B.最后,則是需要在實體類Article中定義一個字段comments,用于接收查詢出來的結(jié)果集中有一方是“列表”的數(shù)據(jù)記錄,如下所示:
@Data
public class Article {//其他字段省略
//子查詢映射
private List<Comment> comments;
}
至此,我們就寫完了相關(guān)的代碼了,接下來,當然是進入自測環(huán)節(jié),不用多講,直接看圖:
至此,基于Spring Boot整合Mybatis實現(xiàn)的關(guān)于“多表關(guān)聯(lián)查詢”業(yè)務場景的實戰(zhàn)就已經(jīng)全部完成了,不知道小伙伴你掌握了沒有呢???
補充:
1、本文涉及到的相關(guān)的源代碼可以到此地址,check出來進行查看學習:
https://gitee.com/steadyjack/SpringBootTechnology
2、關(guān)注一下Debug的技術(shù)微信公眾號唄,最新的技術(shù)文章、技術(shù)課程以及技術(shù)專欄將會第一時間在公眾號發(fā)布哦!