MyBatis 一对多查询(联合查询 ResultMap 映射 和 子查询映射)

前言:

在数据库操作中,我们可能习惯了单表、连表操作,突然然你来进行一对多操作,你还会吗?

什么是一对多?

一对多是最基础的表关系,简单来说就是 A 表中的一条数据对应 B 表中的多条数据,常见场景如下:

  • 部门和人员关系,一个部门对应多个人员。
  • 老师和学生关系,一个老师对应多个学生。
  • 学生和课程成绩关系,一个学生对应多门课程成绩。
  • 。。。。。。

collection 标签

Mybatis 提供了 collection 标签帮助我们简化了一对多关系的查询,collection 标签一般使用于 resultMap 标签中。

collection 属性:

  • property:属性名称。
  • ofType:属性类型。
  • select:关联查询的方法。
  • column:关联字段。

案例

本文以部门和部门下人员作为演示案例,分别有部门表 dept_info 和人员表 employee_info,使用一对多查询部门下的人员。

方法一,联合查询 ResultMap 映射:

java 复制代码
<resultMap id="treeMap" type="com.zt.dc.portal.admin.web.pojo.dto.bulletinboard.DepartmentPersonnelTreeVO">
	<result property="deptName" column="dept_name"/>
	<result property="deptId" column="dept_id"/>
	<result property="parentId" column="parent_id"/>
	<collection property="deptEmployee" ofType="com.zt.dc.portal.admin.web.pojo.entity.EmployeeInfo">
		<result property="name" column="name"/>
		<result property="jobNumber" column="job_number"/>
	</collection>
</resultMap>

<select id="queryDepartmentPersonnel" resultMap="treeMap">
	select di.dept_name ,di.dept_id ,di.parent_id ,ei.name ,ei.job_number
	from dept_info di left join employee_info ei  on di.dept_id =ei.dept_id and ei.emp_type = 1
	where di.dept_type = 1
</select>
  • 原理:sql 直接关联查询,结果集通过 resultMap 的 collection 标签完成一对多的映射。
  • 优点:条件过滤灵活,如果需要进行条件过滤,直接在 where 条件中过滤即可。
  • 缺点:不支持分页,因为是是联合查询后进行映射,无法得到正确的分页效果,如果要分页就先对主表进行分页后再进行关联查询。

方法二,子查询映射:

java 复制代码
<resultMap id="treeMap2" type="com.zt.dc.portal.admin.web.pojo.dto.bulletinboard.DepartmentPersonnelTreeVO">
	<result property="deptName" column="dept_name"/>
	<result property="deptId" column="dept_id"/>
	<result property="parentId" column="parent_id"/>
	<collection property="deptEmployee" select="queryEmployeeInfo" column="dept_id"/>
</resultMap>

<select id="queryDepartmentPersonnel" resultMap="treeMap2">
	select di.dept_name ,di.dept_id ,di.parent_id
	from dept_info di
</select>

<select id="queryEmployeeInfo" resultType="com.zt.dc.portal.admin.web.pojo.entity.EmployeeInfo">
	select ei.name ,ei.job_number from employee_info ei where ei.dept_id=#{deptId}
</select>
  • 原理:通过 collection 标签的 select 属性去调用子查询,查询条件通过 column 属性传递。
  • 优点:普通查询和分页查询都能够支持,主表条件过滤灵活,直接在 where 条件中过滤即可。
  • 缺点:子查询条件过滤比较困难,column 属性只能传递主表已有的字段,多个字段用 column="{prop1=col1,prop2=col2}" 传递。

使用推荐:

建议使用联合查询 ResultMap 映射的方式实现一对多,做了一个小小的测试,两种方式的效率对比,联合查询 ResultMap 映射的方式的效率远高于子查询映射的方式。

欢迎提出建议及对错误的地方指出纠正。

相关推荐
xuxie131 小时前
SpringBoot文件下载(多文件以zip形式,单文件格式不变)
java·spring boot·后端
白鹭1 小时前
MySQL源码部署(rhel7)
数据库·mysql
重生成为编程大王1 小时前
Java中的多态有什么用?
java·后端
666和7771 小时前
Struts2 工作总结
java·数据库
还听珊瑚海吗1 小时前
SpringMVC(一)
数据库
中草药z1 小时前
【Stream API】高效简化集合处理
java·前端·javascript·stream·parallelstream·并行流
野犬寒鸦1 小时前
力扣hot100:搜索二维矩阵 II(常见误区与高效解法详解)(240)
java·数据结构·算法·leetcode·面试
zru_96022 小时前
centos 系统如何安装open jdk 8
java·linux·centos
LiRuiJie2 小时前
深入剖析Spring Boot / Spring 应用中可自定义的扩展点
java·spring boot·spring