SpringBoot系列(五):SpringBoot整合Mybatis实现多表关联查询


作者: 修罗debug
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。

摘要:本文我们将继续分享介绍Spring Boot在整合Mybatis开发企业级应用时其他典型的业务场景,即Mybatis是如何实现多表关联查询时将查询结果集与对象进行映射的,主要的内容包含“一对一的表关联”和“一对多/多对多的表关联”查询。

内容:在上一篇文章中,我们分享介绍了如何基于Spring Boot搭建的标准企业级项目整合第三方的持久层依赖Mybatis,并实现最基本的CRUD功能,此种CRUD估计大伙都明白这是只针对“单一的数据库表”操作的。

而本文我们将趁热打铁,继续分享介绍不一样的内容,即如何基于Mybatis实现“Java对象”与“多表关联查询结果集”的映射。

在开始代码实战之前,我们简单的需要建立两张数据库表,分别是user用户表、comment评论表,其对应的数据库建表语句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='评论';

其中,在上一篇文章中建立的数据库表 “article文章”的user_id即来源于user用户表的主键id,而一篇文章会有很多评论,这些评论信息将存储在comment评论表中,从而,我们可以看出,user与article数据表是平级的关系,而article与comment数据库表则属于一对多的关联关系!

废话不多讲,下面就代码实战环节:

一、数据库表为一对一的平级关联关系实战(涉及user、article表)

(1)首先我们需要明确实战的业务场景:“根据文章的主键id或者文章的详情,在文章的详情中除了需要显示文章的具体信息之外,还需要显示作者的相关信息”。

基于这样的业务场景,首先我们需要将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>


在这里,我们采用的是“左关联”的方式,在获取文章详情的同时,获取该文章所属的作者的相关信息!而为了能让“Java对象”接收存储查询出来的属于用户层面的信息,我们需要在Article类中添加用户相关的“字段信息”,如下所示(在这里我们提前将后文即将要介绍的在一对多映射时需要的comments字段建好了!):  

@Data
public class Article {
private Integer id;

@NotBlank(message = "文章标题不能为空")
private String title;
@NotNull
private Integer userId;

//子查询映射
private List<Comment> comments;

//作者名字
private String userName;
}


紧接着,当然是Controller的代码啦:  

    //多表关联-平级
@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进行自测访问,废话不多讲,看图:  


查看该响应结果中userName字段的值,我们即可大胆的认为我们的写法是没毛病的!当然啦,如果需要显示的用户层面的字段过多,则可以将那些字段信息封装成“实体类”,并在Article类中定义该类的对象实例即可!如果只是几个字段,那就直接定义在Article里面即可!


二、数据库表为一对多/多对多的平级关联关系实战

(1)对于“一对多的数据库表关联实战”,在这里我们采用的是以“一篇文章article,将对应着多条评论记录comment”为案例进行实战。同样的道理,首先我们直接看Mapper.xml中动态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>


在这里,我们采用的仍然是左关联的方式进行表与表之间的关联查询,a.*代表的是文章的详细信息,而b.id,b.content,b.user_id等字段信息代表的是评论表的信息,那最终如何体现出这两个实体对象之间的“一对多关联”关系呢?  很简单,我们只需要做2个步骤:

A.第一是定义查询的结果集映射,即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来实现!

B.最后,则是需要在实体类Article中定义一个字段comments,用于接收查询出来的结果集中有一方是“列表”的数据记录,如下所示:

@Data
public class Article {
//其他字段省略

//子查询映射
private List<Comment> comments;
}


至此,我们就写完了相关的代码了,接下来,当然是进入自测环节,不用多讲,直接看图:  



至此,基于Spring Boot整合Mybatis实现的关于“多表关联查询”业务场景的实战就已经全部完成了,不知道小伙伴你掌握了没有呢???  

补充:

1、本文涉及到的相关的源代码可以到此地址,check出来进行查看学习:

https://gitee.com/steadyjack/SpringBootTechnology

2、关注一下Debug的技术微信公众号呗,最新的技术文章、技术课程以及技术专栏将会第一时间在公众号发布哦!