MyBatis ---- 自定义映射resultMap
- 1. resultMap处理字段和属性的映射关系
- 2. 多对一映射处理
- a>级联方式处理映射关系
- b>使用association处理映射关系
- c>分布查询
- 3. 一对多映射处理
- a>collection
- b>分步查询
1. resultMap处理字段和属性的映射关系
当实体类中的属性名和数据库中的属性名不一致时
<!--List<Emp> getAllEmp();-->
<select id="getAllEmp" resultType="emp">
select * from t_emp;
</select>
输出时并不会报异常,而是对于属性值不一样的值,输出结果为 null
解决方案:
- 为字段起别名的方式,保证和实体类中的属性名保持一致
<!--List<Emp> getAllEmp();-->
<select id="getAllEmp" resultType="emp">
<!--select * from t_emp;-->
select eid, emp_name empName, age, sex, email from t_emp;
</select>
- 可以在 MyBatis 的核心配置文件中设置一个全局配置信息
mapUnderscoreToCamelCase
<!--配置MyBatis的全局变量-->
<settings>
<!--自动将_映射为驼峰规则-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!--List<Emp> getAllEmp();-->
<select id="getAllEmp" resultType="emp">
<!--select * from t_emp;-->
<!--select eid, emp_name empName, age, sex, email from t_emp;-->
select * from t_emp;
</select>
- 通过 resultMap 自定义映射
<resultMap id="EmpResultMap" type="emp">
<id property="eid" column="eid"></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>
</resultMap>
<!--List<Emp> getAllEmp();-->
<select id="getAllEmp" resultMap="EmpResultMap">
select * from t_emp;
</select>
resultMap:设置自定义映射
属性:
id:表示自定义映射的唯一标识
type:查询的数据要映射的实体类的类型
子标签:
id:设置主键的映射关系
result:设置普通字段的映射关系
property:设置映射关系中实体类中的属性名
column:设置映射关系中表中的字段名
2. 多对一映射处理
a>级联方式处理映射关系
<resultMap id="empDeptMap" type="emp">
<id property="eid" column="eid"></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.did" column="did"></result>
<result property="dept.deptName" column="dept_name"></result>
</resultMap>
<!--Emp getEmpAndDeptByEid(@Param("eid") Integer eid);-->
<select id="getEmpAndDeptByEid" resultMap="empDeptMap">
select * from t_emp left join t_dept on t_emp.did = t_dept.did where t_emp.eid = #{eid};
</select>
b>使用association处理映射关系
<resultMap id="empDeptMap" type="emp">
<id property="eid" column="eid"></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 property="dept" javaType="Dept">
<id property="did" column="did"></id>
<result property="deptName" column="dept_name"></result>
</association>
</resultMap>
<!--Emp getEmpAndDeptByEid(@Param("eid") Integer eid);-->
<select id="getEmpAndDeptByEid" resultMap="empDeptMap">
select * from t_emp left join t_dept on t_emp.did = t_dept.did where t_emp.eid = #{eid};
</select>
c>分布查询
- 查询员工信息
/**
* 分布查询第一步
* @param eid
* @return
*/
Emp getEmpByStepOne(@Param("eid") Integer eid);
<resultMap id="empAndDeptByStep" type="emp">
<id property="eid" column="eid"></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 property="dept" select="com.fickler.mybatis.mapper.DeptMapper.getDeptByStepTwo" column="did"></association>
</resultMap>
<!--Emp getEmpByStepOne(@Param("eid") Integer eid);-->
<select id="getEmpByStepOne" resultMap="empAndDeptByStep">
select * from t_emp where eid = #{eid};
</select>
- 根据员工所对应的部门id查询部门信息
/**
* 分布查询第二步
* @param did
* @return
*/
Dept getDeptByStepTwo(@Param("did") Integer did);
<!--Dept getDeptByStepTwo(@Param("did") Integer did);-->
<select id="getDeptByStepTwo" resultType="dept">
select * from t_dept where did = #{did}
</select>
分布查询的优点:
可以实现延迟加载,但是必须在核心配置文件中设置全局配置信息:
lazyLoadingEnabled:延迟加载的全局开关。当开启时,所有关联对象都会延迟加载
aggressiveLazyLoading:当开启时,任何方法的调用都会加载该对象的所有属性。否则,每个属性会按需加载
此时就可以实现按需加载,获取的数据是什么,就只会执行相应的 sql。此时可通过 association 和 collection 中的 fetchType 属性设置当前的分步查询是否使用延迟加载,fetchType = “lazy(延迟加载)|eager(立即加载)”
lazyLoadingEnabled
<!--配置MyBatis的全局变量-->
<settings>
<!--自动将_映射为驼峰规则-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!--开启延迟加载-->
<setting name="lazyLoadingEnabled" value="true"/>
</settings>
@Test
public void testGetEmpAndDeptByStep(){
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);
Emp empByStepOne = empMapper.getEmpByStepOne(5);
System.out.println(empByStepOne.getEmpName());
}
只执行第一个 sql 语句
aggressiveLazyLoading
开启之后,是立即加载
<!--配置MyBatis的全局变量-->
<settings>
<!--自动将_映射为驼峰规则-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!--开启延迟加载-->
<setting name="lazyLoadingEnabled" value="true"/>
<!--实现立即加载-->
<setting name="aggressiveLazyLoading" value="true"/>
</settings>
fetchType
fetchType 的值为 eager,为立即加载,即使全局配置中设置为延迟加载,fetchType 可以按需设置为立即加载
<!--配置MyBatis的全局变量-->
<settings>
<!--自动将_映射为驼峰规则-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!--开启延迟加载-->
<setting name="lazyLoadingEnabled" value="true"/>
<!--实现立即加载-->
<!-- <setting name="aggressiveLazyLoading" value="true"/>-->
</settings>
<resultMap id="empAndDeptByStep" type="emp">
<id property="eid" column="eid"></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 property="dept" fetchType="eager" select="com.fickler.mybatis.mapper.DeptMapper.getDeptByStepTwo" column="did"></association>
</resultMap>
此时为 延迟加载
<resultMap id="empAndDeptByStep" type="emp">
<id property="eid" column="eid"></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 property="dept" fetchType="lazy" select="com.fickler.mybatis.mapper.DeptMapper.getDeptByStepTwo" column="did"></association>
</resultMap>
3. 一对多映射处理
a>collection
/**
* 查询部门中的所有员工信息
* @param did
* @return
*/
Dept getDeptEmpByDid(@Param("did") Integer did);
<resultMap id="deptEmpByDid" type="dept">
<id property="did" column="did"></id>
<result property="deptName" column="dept_name"></result>
<collection property="emps" ofType="emp">
<id property="eid" column="eid"></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>
</collection>
</resultMap>
<!--Dept getDeptEmpByDid(@Param("did") Integer did);-->
<select id="getDeptEmpByDid" resultMap="deptEmpByDid">
select * from t_dept left join t_emp on t_dept.did = t_emp.did where t_dept.did = #{did};
</select>
b>分步查询
- 查询部门信息
/**
* 分布查询第一步
* @param did
* @return
*/
Dept getDeptByStep(@Param("did") Integer did);
<resultMap id="deptEmpStep" type="dept">
<id property="did" column="did"></id>
<result property="deptName" column="dept_name"></result>
<collection property="emps" select="com.fickler.mybatis.mapper.EmpMapper.getEmpByStep" column="did"></collection>
</resultMap>
<!--Dept getDeptByStep(@Param("did") Integer did);-->
<select id="getDeptByStep" resultMap="deptEmpStep">
select * from t_dept where t_dept.did = #{did};
</select>
- 根据部门 id 查询部门中的所有员工
/**
* 分组查询第二步
* @param did
* @return
*/
Emp getEmpByStep(@Param("did") Integer did);
<!--Emp getEmpByStep(@Param("eid") Integer did);-->
<select id="getEmpByStep" resultType="emp">
select * from t_emp where t_emp.did = #{did};
</select>