八、自定义映射resultMap
# 8.1、resultMap处理字段和属性的映射关系
若字段名和实体类中的属性名不一致,则可以通过resultMap设置自定义映射
<!--
resultMap:设置自定义映射
属性:
id:表示自定义映射的唯一标识
type:查询的数据要映射的实体类的类型
常用子标签:
id:设置主键的映射关系
result:设置普通字段的映射关系
association:设置多对一的映射关系
collection:设置一对多的映射关系
子标签属性:
property:设置映射关系中实体类中的属性名
column:设置映射关系中表中的字段名
-->
<resultMap id="empResultMap" type="Emp">
<id column="emp_id" property="empId"></id>
<result column="emp_name" property="empName"/>
<result column="age" property="age"/>
<result column="gender" property="gender"/>
</resultMap>
<!--Emp getEmpByEmpId(@Param("empId") Integer empId);-->
<select id="getEmpByEmpId" resultMap="empResultMap">
select * from t_emp where emp_id = #{empId}
</select>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
若字段名和实体类中的属性名不一致,但是字段名符合数据库的规则(使用_),实体类中的属性名符合Java的规则(使用驼峰)
此时也可通过以下两种方式处理字段名和实体类中的属性的映射关系:
a>可以通过为字段起别名的方式,保证和实体类中的属性名保持一致
b>可以在MyBatis的核心配置文件中设置一个全局配置信息
mapUnderscoreToCamelCase
,可以在查询表中数据时,自动将_类型的字段名转换为驼峰例如:字段名
user_name
,设置了mapUnderscoreToCamelCase
,此时字段名就会转换为userName
# 8.2、多对一映射处理(例如多个员工对应一个部门,每个员工中都对应着一个部门)
场景模拟:
查询员工信息以及员工所对应的部门信息
# 8.2.1、级联方式处理映射关系
为员工中的部门对象的属性单独配置result标签,当然
<resultMap id="empAndEdptResultMap" type="Emp">
<id column="emp_id" property="empId"></id>
<result column="emp_name" property="empName"></result>
<result column="age" property="age"></result>
<result column="gender" property="gender"></result>
<result column="dept_id" property="dept.deptId"></result>
<result column="dept_name" property="dept.deptName"></result>
</resultMap>
<!--Emp getEmpAndDeptByEmpId(@Param("empId") Integer empId);-->
<select id="getEmpAndDeptByEmpId" resultMap="empAndEdptResultMap">
select t_emp.*, t_dept.* from t_emp left join t_dept on t_emp.dept_id = t_dept.dept_id where t_emp.emp_id = #{empId}
</select>
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 8.2.2、使用association处理映射关系
在association中写属性类的相关映射
<resultMap id="empAndEdptResultMap" type="Emp">
<id column="emp_id" property="empId"></id>
<result column="emp_name" property="empName"></result>
<result column="age" property="age"></result>
<result column="gender" property="gender"></result>
<association property="dept" javaType="Dept">
<id column="dept_id" property="deptId"></id>
<result column="dept_name" property="deptName"></id>
</association>
</resultMap>
<!--Emp getEmpAndDeptByEmpId(@Param("empId") Integer empId);-->
<select id="getEmpAndDeptByEmpId" resultMap="empAndEdptResultMap">
select t_emp.*, t_dept.* from t_emp left join t_dept on t_emp.dept_id = t_dept.dept_id where t_emp.emp_id = #{empId}
</select>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 8.2.3、分步查询
一步步去查询,分布查询时子查询出的类型一定要和我们要操作的类型是一致的
# ①查询员工信息
/**
* 通过分步查询查询员工信息
* @param empId
* @return
*/
Emp getEmpAndDeptByStepOne(@Param("empId") Integer empId);
1
2
3
4
5
6
2
3
4
5
6
<resultMap id="empAndDeptByStepResultMap" type="Emp">
<id column="emp_id" property="empId"></id>
<result column="emp_name" property="empName"></result>
<result column="age" property="age"></result>
<result column="gender" property="gender"></result>
<!--
property:需要映射的实体类中的属性类的属性名
select:设置分步查询,查询某个属性的值的sql的标识(namespace.sqlId)
column:将查询结果中的某个字段设置为下一个分步查询的条件
fetchType:通过该属性设置当前的分布查询是否使用延迟加载,不需要全局配置延迟加载
fetchType="eager(立即加载)|lazy(延迟加载)"
-->
<association property="dept"
select="com.atguigu.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwo"
column="dept_id">
</association>
</resultMap>
<!--Emp getEmpAndDeptByStepOne(@Param("empId") Integer empId);-->
<select id="getEmpAndDeptByStepOne" resultMap="empAndDeptByStepResultMap">
select * from t_emp where emp_id = #{empId}
</select>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# ②根据员工所对应的部门id查询部门信息
/**
* 分步查询的第二步: 根据员工所对应的did查询部门信息
* @param deptId
* @return
*/
Dept getEmpAndDeptByStepTwo(@Param("deptId") Integer deptId);
1
2
3
4
5
6
2
3
4
5
6
<!--Dept getEmpAndDeptByStepTwo(@Param("deptId") Integer deptId);-->
<select id="getEmpAndDeptByStepTwo" resultType="com.atguigu.mybatis.pojo.Dept">
select * from t_dept where dept_id = #{deptId}
</select>
1
2
3
4
2
3
4
# 8.3、一对多映射处理(例如一个部门对应多个员工,一个部门对象中存储着多个员工对象)
查询一个部门以及这个部门中所有的员工
# 8.3.1、collection
/**
* 根据部门id查新部门以及部门中的员工信息
* @param deptId
* @return
*/
Dept getDeptAndEmpByDeptId(@Param("deptId") Integer deptId);
1
2
3
4
5
6
2
3
4
5
6
<resultMap id="deptAndEmpResultMap" type="Dept">
<id column="dept_id" property="deptId"></id>
<result column="dept_name" property="deptName"></result>
<collection property="emps" ofType="Emp">
<id column="emp_id" property="empId"></id>
<result column="emp_name" property="empName"></result>
<result column="age" property="age"></result>
<result column="gender" property="gender"></result>
</collection>
</resultMap>
<!--Dept getDeptAndEmpByDeptId(@Param("deptId") Integer deptId);-->
<select id="getDeptAndEmpByDeptId" resultMap="deptAndEmpResultMap">
select * from t_dept left join t_emp on t_dept.dept_id = t_emp.dept_id where t_dept.dept_id = #{deptId}
</select>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 8.3.2、分步查询
# ①查询部门信息
/**
* 分步查询部门和部门中的员工
* @param deptId
* @return
*/
Dept getDeptAndEmpByStepOne(@Param("deptId") Integer deptId);
1
2
3
4
5
6
2
3
4
5
6
<resultMap id="deptAndEmpResultMapByStep" type="Dept">
<id column="dept_id" property="deptId"></id>
<result column="dept_name" property="deptName"></result>
<collection property="emps"
select="com.atguigu.mybatis.mapper.EmpMapper.getDeptAndEmpByStepTwo"
column="dept_id"></collection>
</resultMap>
<!--Dept getDeptAndEmpByStepOne(@Param("deptId") Integer deptId);-->
<select id="getDeptAndEmpByStepOne" resultMap="deptAndEmpResultMapByStep">
select * from t_dept where dept_id = #{deptId}
</select>
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# ②根据部门id查询部门中的所有员工
/**
* 根据部门id查询员工信息
* @param deptId
* @return
*/
List<Emp> getDeptAndEmpByStepTwo(@Param("deptId") Integer deptId);
1
2
3
4
5
6
2
3
4
5
6
<!--List<Emp> getDeptAndEmpByStepTwo(@Param("deptId") Integer deptId); -->
<select id="getDeptAndEmpByStepTwo" resultType="com.atguigu.mybatis.pojo.Emp">
select * from t_emp where dept_id = #{deptId}
</select>
1
2
3
4
2
3
4
分步查询的优点:可以实现延迟加载
但是必须在核心配置文件中设置全局配置信息:
lazyLoadingEnabled
:延迟加载的全局开关。当开启时,所有关联对象都会延迟加载
aggressiveLazyLoading
:当开启时,任何方法的调用都会加载该对象的所有属性。否则,每个属性会按需加载,也就是说,若要使用延迟加载,需要将该属性设置为false此时就可以实现按需加载,获取的数据是什么,就只会执行相应的sql,且为全局配置
此时可通过
association
和collection
中的fetchType
属性设置当前的分步查询是否使用延迟加载,fetchType="lazy(延迟加载)|eager(立即加载)"
编辑 (opens new window)
上次更新: 2024/05/30, 07:49:34