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 映射的方式的效率远高于子查询映射的方式。

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

相关推荐
ejinxian25 分钟前
PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis, OceanBase, Sql Server等数据库
数据库·mysql·mongodb
折哥的程序人生 · 物流技术专研7 小时前
Java面试85题图解版 · 特别篇:2026后端高频面试题复盘(算法底层逻辑+高并发架构设计全解析,附Java实战代码)
java·网络·数据库·算法·面试
AOwhisky7 小时前
Redis 学习笔记(第三期):持久化与主从复制
运维·数据库·redis·笔记·学习·云计算
李白的天不白7 小时前
数据库连接报错问题
数据库
一条泥憨鱼7 小时前
【Redis】数据类型和常用命令
java·数据库·redis·后端·缓存
云烟成雨TD7 小时前
Spring AI Alibaba 1.x 系列【78】沙箱(Sandbox)
java·人工智能·spring
程序员二叉7 小时前
【Java】 异常高频面试题精讲 | 易错点+对比总结
java·开发语言·面试
爱喝水的鱼丶8 小时前
SAP-ABAP:SAP视图开发入门:四类标准视图的适用场景与创建步骤详解
服务器·数据库·性能优化·sap·abap
周航宇JoeZhou8 小时前
JB3-9-SpringAI(二)
java·ai·agent·多智能体·调度·智能体·观察
好家伙VCC8 小时前
Web Components主题热切换方案揭秘
java·前端