Mybatis_结果封装

本文详细解析MyBatis中ResultType与ResultMap的使用方法,包括如何通过ResultType自动封装查询结果到POJO或Map,以及ResultMap在列名与属性名不一致时、多表关联查询时的高级应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

select查询标签的两个属性:

resultType:用于指定返回结果集的类型
resultMap:在查询的结果集不便于封装,或者多表关联查询时,替代resultType自定义返回结果类型。

一.ResultType示例

Employee【员工表】
EMPLOYEE(员工表)
对应的实体类【注意last_name并未开启驼峰命名,无法直接映射】

public class Employee {
	private Integer id;
	private String lastName;
	private String email;
	private String gender;
	private Department dept;
	
	constructor...
	getter and setter...
}

查询语句mapper以及对应的接口方法:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 
<mapper namespace="com.tt.mybatis.dao.EmployeeMapper">
 	<!-- public Employee getEmpById(Integer id); -->
 	<select id="getEmpById" resultType="com.tt.mybatis.bean.Employee">
 		select id,last_name lastName from tbl_employee where id=#{id}
 	</select>
 	
	<!-- public List<Employee> getEmps(); -->
	<select id="getEmps" resultType="com.tt.mybatis.bean.Employee">
		select id,last_name lastName from tbl_employee
	</select>

	<!--public Map<String, Object> getEmpByIdReturnMap(Integer id);  -->
 	<select id="getEmpByIdReturnMap" resultType="map">
 		select id,last_name lastName from tbl_employee where id=#{id}
 	</select>

	<!--
		@MapKey("id")
		public Map<Integer, Employee> getEmpsReturnMap();  
	-->
 	<select id="getEmpsReturnMap" resultType="com.tt.mybatis.bean.Employee">
 		select id,last_name lastName from tbl_employee
 	</select> 	
</mapper>

总结
1、resultType指定pojo或者map,可以将查询结果自动封装成pojo或者map。
注意:在未开启驼峰命名规则时,查询的列名与实体类的属性名完全一致才能自动封装。
2、如果返回的是List,resultType只需指定集合中元素的类型。
3、如果需要返回Map<Integer,Employee>这种格式,resultType指定map中value的值,map中key的值由mapper接口方法@MapKey()来指定。


二.ResultMap示例

Employee【员工表d_id外键关联部门表id主键】
EMPLOYEE(员工表)
Department【部门表】
部门表

对应的实体类

public class Employee {
	private Integer id;
	private String lastName;
	private String email;
	private String gender;
	private Department dept;
	
	constructor...
	getter and setter...
}
public class Department {
	private Integer id;
	private String departmentName;
	private List<Employee> emps;
	
	constructor...
	getter and setter...	
}

对应的mapper接口:

public interface EmployeeMapperPlus {
	
	public Employee getEmpById(Integer id);
	
	public Employee getEmpAndDept(Integer id);
	
	public Employee getEmpByIdStep(Integer id);
	
	public List<Employee> getEmpsByDeptId(Integer deptId);

}
public interface DepartmentMapper {
	
	public Department getDeptById(Integer id);
	
	public Department getDeptByIdPlus(Integer id);

	public Department getDeptByIdStep(Integer id);
}
场景一:使用resultMap封装列名与属性名不一致时的结果类
<!--
	id: 指定主键列的封装规则
		column:指定哪一列 
		property:指定对应的javaBean属性
	result: 指定普通列的封装规则
-->
<resultMap type="com.tt.mybatis.bean.Employee" id="MySimpleEmp">
	<id column="id" property="id"/>
	<result column="last_name" property="lastName"/>
	<result column="email" property="email"/>
	<result column="gender" property="gender"/>
</resultMap>

<!-- public Employee getEmpById(Integer id); -->
<select id="getEmpById"  resultMap="MySimpleEmp">
	select * from tbl_employee where id=#{id}
</select>
场景二:查询Employee的同时查询员工对应的部门
1、级联属性封装结果集
<resultMap type="com.atguigu.mybatis.bean.Employee" id="MyDifEmp">
	<id column="id" property="id"/>
	<result column="last_name" property="lastName"/>
	<result column="gender" property="gender"/>
	<result column="did" property="dept.id"/>
	<result column="departmentName " property="dept.departmentName"/>
</resultMap>

<!--  public Employee getEmpAndDept(Integer id);-->
<select id="getEmpAndDept" resultMap="MyDifEmp">
	SELECT e.id id,e.last_name last_name,e.gender gender,e.d_id d_id,
		d.id did,d.departmentName departmentName 
	FROM tbl_employee e,tbl_dept d
	WHERE e.d_id=d.id AND e.id=#{id}
</select>
2、使用association定义关联对象封装规则
<!--  
	association定:义关联对象的封装规则
		property:指定哪个属性是关联的对象
		javaType:指定这个属性对象的类型[不能省略]
-->
<resultMap type="com.tt.mybatis.bean.Employee" id="MyDifEmp2">
	<id column="id" property="id"/>
	<result column="last_name" property="lastName"/>
	<result column="gender" property="gender"/>
	<association property="dept" javaType="com.tt.mybatis.bean.Department">
		<id column="did" property="id"/>
		<result column="departmentName" property="departmentName"/>
	</association>
</resultMap>
<!--  public Employee getEmpAndDept(Integer id);-->
<select id="getEmpAndDept" resultMap="MyDifEmp">
	SELECT e.id id,e.last_name last_name,e.gender gender,e.d_id d_id,
	d.id did,d.departmentName departmentName 
	FROM tbl_employee e,tbl_dept d
	WHERE e.d_id=d.id AND e.id=#{id}
</select>
3、使用association分步查询
<!-- 
	association定义关联对象的封装规则
 		select:表明当前属性是调用select指定的方法查出的结果
 		column:指定将哪一列的值传给这个方法
-->
 <resultMap type="com.tt.mybatis.bean.Employee" id="MyEmpByStep">
 	<id column="id" property="id"/>
 	<result column="last_name" property="lastName"/>
 	<result column="email" property="email"/>
 	<result column="gender" property="gender"/>
	<association property="dept" 
		select="com.tt.mybatis.dao.DepartmentMapper.getDeptById"
		column="d_id">
	</association>
 </resultMap>
 <!--  public Employee getEmpByIdStep(Integer id);-->
 <select id="getEmpByIdStep" resultMap="MyEmpByStep">
 	select * from tbl_employee where id=#{id}
 </select>
场景三:查询Department的同时查询部门下的员工
1.使用collection定义关联集合封装规则
<!-- 
	collection定义关联集合类型的属性的封装规则 
	ofType:指定集合里面元素的类型
-->
<resultMap type="com.tt.mybatis.bean.Department" id="MyDept">
	<id column="did" property="id"/>
	<result column="departmentName" property="departmentName"/>
	<collection property="emps" ofType="com.tt.mybatis.bean.Employee">
		<!-- 定义这个集合中元素的封装规则 -->
		<id column="eid" property="id"/>
		<result column="last_name" property="lastName"/>
		<result column="email" property="email"/>
		<result column="gender" property="gender"/>
	</collection>
</resultMap>
<!-- public Department getDeptByIdPlus(Integer id); -->
<select id="getDeptByIdPlus" resultMap="MyDept">
	SELECT d.id did,d.departmentName departmentName,
		   e.id eid,e.last_name last_name,e.email email,e.gender gender
	FROM tbl_dept d LEFT JOIN tbl_employee e
	ON d.id=e.d_id
	WHERE d.id=#{id}
</select>
2.使用collection分步查询
<resultMap type="com.tt.mybatis.bean.Department" id="MyDeptStep">
	<id column="id" property="id"/>
	<id column="dept_name" property="departmentName"/>
	<collection property="emps" 
		select="com.tt.mybatis.dao.EmployeeMapperPlus.getEmpsByDeptId"
		column="id" fetchType="lazy"></collection>
</resultMap>
<!-- public Department getDeptByIdStep(Integer id); -->
<select id="getDeptByIdStep" resultMap="MyDeptStep">
	select id,dept_name from tbl_dept where id=#{id}
</select>

总结
1.通过级联查询和association/collection定义关联对象/集合封装规则,这两种方式是直接发送一条sql,查询两张表得到所有数据
而利用association/collection分步查询是发送两条sql,先查询主表得到关联外键后再查询从表
如果全局配置文件中设置了懒加载,只有在使用到从表数据才会进行查询。
2.懒加载的设置:在mybatis全局配置文件中设置。

	<settings>
		<!-- 驼峰命名默认false关闭 -->
		<setting name="mapUnderscoreToCamelCase" value="false"/>
		<!-- 开启懒加载 -->
		<setting name="lazyLoadingEnabled" value="true"/>
		<setting name="aggressiveLazyLoading" value="false"/>
	</settings>

当全局配置文件中开启懒加载设置时,想设置某个查询语句立即加载。
在association和collection标签中有fetchType属性默认为lazy,可以设置为eager设置该查询语句立即加载。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值