resultType和resultMap用法详解 | Mybatis
输入映射
首先要明白的是Mybatis的输入与输出映射都是相对于数据库而言的
。
输入映射(parameterType):将POJO中的属性映射到sql语句的占位符,进而与数据库表中的字段做映射。
输出映射
在将数据库表中的字段
和POJO中的属性
进行映射时,Mybatis提供了自动映射resultType和自定义映射resultMap两个标签来完成这一系列操作。
- resultType:自动映射,用于属性名和表中字段名一致的情况。
- resultMap:自定义映射,用于字段名和属性名不一致、一对多映射、多对一映射的情况。
一、使用resultType完成自动映射
resultType
:自动映射,用于属性名和表中字段名一致的情况。
二、使用resultMap完成自定义映射
上面演示的resultType在字段名和属性名一致的情况下,完成了自动映射,而当两者不一致时就需要使用resultMap来完成自定义映射。
resultMap
:自定义映射,用于字段名和属性名不一致、一对多映射、多对一映射的情况。
使用resultMap完成自定义映射,resultMap标签说明:
resultMap:设置自定义映射
属性:
id:唯一标识
type:自定义映射需要处理的类型
子标签:
id:设置主键和属性的映射关系
result:设置普通字段和属性的映射关系
property:设置映射关系中的属性名
column:设置映射关系中的字段名
association:设置多对一的映射关系
javaType:设置该属性的类型
select:设置分步查询的sql的唯一标识
column:作为分步查询的条件的字段名
fetchType:lazy延迟加载;eager立即加载
collection:设置一对多的映射关系
多对一映射
方案1:级联方式处理
级联方式处理多对一:
关键语句:property="dept.deptId"
,其中property表示的是实体类的属性名。
在多对1的映射中,需在多方添加1方的值。级联调用就是在property标签中,通过1方POJO的别名调用到对应的属性。进而通过使用resultMap的property和column标签,在属性名和字段名之间建立映射。
<mapper namespace="com.gql.mapper.EmpMapper">
<resultMap id="empResultMap" type="Emp">
<id property="empId" column="emp_id"></id>
<result property="empName" column="emp_name"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
<result property="email" column="email"></result>
<!-- 级联属性赋值-->
<result property="dept.deptId" column="dept_id"></result>
<result property="dept.deptName" column="dept_id"></result>
</resultMap>
<!--Emp getEmpByResultMap(@Param("empId") Integer empId);-->
<select id="getEmpByResultMap" resultMap="empResultMap">
select emp.*, dept.*
from t_emp emp
left join t_dept dept
on emp.dept_id = dept.dept_id
where emp.emp_id = #{empId}
</select>
</mapper>
方案2:使用association标签处理
关键代码:
<association property="dept" javaType="Dept"> <id property="deptId" column="dept_id"></id> <result property="deptName" column="dept_name"></result> </association>
association标签:专门用来设置多对1的映射关系。
javaType
:设置该属性的类型。property
:设置映射关系中的属性名。column
:设置映射关系中的字段名。使用association进行处理多对一映射时,可以将association标签的子标签看作是resultMap标签的子标签,当作是设置另一张表自定义映射来帮助理解。
<mapper namespace="com.gql.mapper.EmpMapper">
<resultMap id="empResultMap" type="Emp">
<id property="empId" column="emp_id"></id>
<result property="empName" column="emp_name"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
<result property="email" column="email"></result>
<!-- association设置对象字段映射关系-->
<association property="dept" javaType="Dept">
<id property="deptId" column="dept_id"></id>
<result property="deptName" column="dept_name"></result>
</association>
</resultMap>
<!--Emp getEmpByResultMap(@Param("empId") Integer empId);-->
<select id="getEmpByResultMap" resultMap="empResultMap">
select emp.*, dept.*
from t_emp emp
left join t_dept dept
on emp.dept_id = dept.dept_id
where emp.emp_id = #{empId}
</select>
</mapper>
方案3:分步查询实现多对一
分步查询:
select
:设置分步查询的sql的唯一标识。
column
:作为分步查询的条件的字段名。<association property="dept" fetchType="lazy" select="com.gql.mapper.DeptMapper.getEmpDeptByStep" column="dept_id"> </association>
分步查询的优点:可以实现延迟加载,但是必须在核心配置文件中设置全局配置信息:
此时就可以实现按需加载,获取的数据是什么,就只会执行相应的sql。此时可通过association和collection中的fetchType属性设置当前的分步查询是否使用延迟加载,fetchType=“lazy(延迟加载)|eager(立即加载)”
分步查询的优点:可以实现延迟加载,但是必须在核心配置文件中设置全局配置信息:
此时就可以实现按需加载,获取的数据是什么,就只会执行相应的sql。此时可通过association和collection中的fetchType属性设置当前的分步查询是否使用延迟加载,fetchType=“lazy(延迟加载)|eager(立即加载)”
一对多映射
方案1:使用collection处理
collection标签:ofType:设置collection标签所处理的集合属性中存储数据的类型。
方案2:分步查询实现一对多
collection:设置一对多的映射关系。
- property:设置映射关系中的属性名(这里将对象作为一个属性)
- select:设置分步查询sql的唯一标识。
- column:作为分步查询的条件的字段名。