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