自定义映射resultMap
一、resultMap处理字段和属性的映射关系
-
为字段设置别名,是别名和属性名一致(方式一)
<select id="getAllEmp" resultType="Emp"> select eid, emp_name empName, age, sex, email from t_emp where eid = #{eid} </select>
-
在mybatis-config.xml中,使用setting标签设置全局变量(方式二)
<settings> <!-- 将数据库中的带下划线的字段名映射为驼峰命名方式。如emp_name:empName --> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings>
-
使用resultMap设定(方式三)
<mapper namespace="com.atguigu.mybatis.mapper.EmpMapper"> <!-- resultMap:设置自定义映射关系 id:唯一标识,不能重复 type:设置映射关系中的实体类类型 子标签:、 id:设置主键的关系 result:设置普通字段的映射关系 属性: property:设置映射关系中的属性名,且必须是type属性所设置的实体类类型中的属性名 column:设置映射关系中的数据表中的字段名, --> <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> <select id="getAllEmp" resultMap="empResultMap"> select * from t_emp where eid = #{eid} </select> </mapper>
二、多对一
-
表和表之间有对应关系,则与表相对应的实体类之间也有关系,故要在多对一关系中的多的实体类中创建一的实体类对象属性
public class Emp{ private Integer eid; private String empName; private Integer age; private Character sex; private String email; // 关系中一的对象属性 private Dept dept; public Emp() {} // 全参构造器中没有对象属性 public Emp(Integer eid, String empName, Integer age, Character sex, String email) { this.eid = eid; this.empName = empName; this.age = age; this.sex = sex; this.email = email; } // 以及各属性的get/set/toString方法 }
-
使用级联属性赋值,解决多对一的映射问题(方式一)
<!-- 处理多对一的映射关系方式一 --> <resultMap id="empAndDeptMapOne" 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> <select id="getEmpAndDept" resultMap="empAndDeptMapOne"> select * from t_emp left join t_dept on t_emp.did = t_dept.did where t_emp.eid = #{eid} </select>
-
使用association标签,解决多对一的映射问题(方式二)
javaType:一的实体类型
<!-- 处理多对一的映射关系方式二 --> <resultMap id="empAndDeptMapTwo" 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> <select id="getEmpAndDept" resultMap="empAndDeptMapTwo"> select * from t_emp left join t_dept on t_emp.did = t_dept.did where t_emp.eid = #{eid} </select>
-
使用分步查询,解决多对一的映射问题(方式三)
第一步
mapper接口
public interface EmpMapper { // 分步查询员工及员工所对应的部门信息第一步 Emp getEmpAndDeptByStepOne(@Param("eid") Integer eid); }
mapper映射文件
<resultMap id="empAndDeptByStepResultMap" type="Emp"> <id property="eid" column="eid"/> <result property="empName" column="emp_name"/> <result property="age" column="age"/> <result property="sex" column="sex"/> <result property="email" column="email"/> <!-- property:关联的实体类属性 select:是第二步中查询该实体类的sql语句对应的接口中的方法的全类名 column:第二步sql语句查询的条件 --> <association property="dept" select="com.atguigu.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwo" column="did"/> </resultMap> <select id="getEmpAndDeptByStepOne" resultMap="empAndDeptByStepResultMap"> select * from t_emp where eid = #{eid} </select>
第二步
mapper接口
public interface DeptMapper { // 分步获取部门以及部门中所有员工的信息 Dept getDeptAndEmpByStepTwo(@Param("did") Integer did); }
mapper映射文件
<!-- 此处使用resultType就可以了 --> <select id="getEmpAndDeptByStepTwo" resultType="Dept"> select * from t_dept where did = #{did} </select>
三、延迟加载
-
分步查询的优点:就是可以**实现延迟加载
-
lazyLoadingEnabled
延迟加载的全局开关,默认关闭(false),开启后,所有关联对象都会延迟加载
<!-- 在mybatis-config.xml中 --> <settings> <!-- 处理字段名和属性名对应的方法一:将数据库中的带下划线字段名映射为驼峰命名方式。如emp_name:empName --> <setting name="mapUnderscoreToCamelCase" value="true"/> <!-- 开启延迟加载 --> <setting name="lazyLoadingEnabled" value="true"/> </settings>
-
aggressiveLazyLoading
开启时,任何方法的调用都会加载该对象的所有属性,即延时加载无效
关闭时:每个属性会按需加载,即延时加载有效(默认)
-
fetchType
对单个映射功能是否延时加载进行单独设置
<resultMap id="empAndDeptByStepResultMap" type="Emp"> <id property="eid" column="eid"/> <result property="empName" column="emp_name"/> <result property="age" column="age"/> <result property="sex" column="sex"/> <result property="email" column="email"/> <!-- fetchType:用于在setting中设置了全局延迟加载后,对该映射功能是否延迟加载进行单独设置 lazy表示延时加载(默认) eager表示不延时加载 --> <association property="dept" select="com.atguigu.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwo" column="did" fetchType="lazy"/> </resultMap>
-
测试
@Test public void empAndDeptMapByStepTest() { SqlSession sqlSession = SqlSessionUtil.getSqlSession(); EmpMapper mapper = sqlSession.getMapper(EmpMapper.class); Emp emp = mapper.getEmpAndDeptByStepOne(3); // 开启延时加载,如果只是获取empName属性,并不会执行第二步 System.out.println(emp.getEmpName()); System.out.println("+++++++++++++++++++++++++++++++++"); System.out.println(emp.getDept()); }
四、一对多
-
在一对多关系中的一的实体类中创建多的实体类对象属性
public class Dept { private Integer did; private String deptName; private List<Emp> emps; public Dept() { } public Dept(Integer did, String deptName) { this.did = did; this.deptName = deptName; } // 全部属性的get/set/toString方法 }
-
使用collocation标签,解决一对多的映射问题(方式一)
第一步
mapper接口
public interface DeptMapper { // 获取部门以及部门中所有员工的信息 Dept getDeptAndEmp(@Param("did") Integer did); }
mapper映射文件
<!-- ofType:在列表中的类型 --> <resultMap id="DeptAndEmpResultMap" type="Dept"> <id property="did" column="did"/> <result property="deptName" column="dept_name"/> <collection property="emps" ofType="Emp"> <id property="eid" column="eid"/> <result property="empName" column="emp_name"/> <result property="age" column="age"/> <result property="sex" column="sex"/> <result property="email" column="email"/> </collection> </resultMap> <select id="getDeptAndEmp" resultMap="DeptAndEmpResultMap"> select * from t_dept left join t_emp on t_dept.did = t_emp.did where t_dept.did = #{did} </select>
-
使用collocation标签,解决一对多的映射问题(方式一)
第一步
mapper接口
public interface DeptMapper { // 分步获取部门以及部门中所有员工的信息 Dept getDeptAndEmpByStepOne(@Param("did") Integer did); }
mapper映射文件
<resultMap id="DeptAndEmpResultByStepMap" type="Dept"> <id property="did" column="did"/> <result property="dept_name" column="deptName"/> <collection property="emps" select="com.atguigu.mybatis.mapper.EmpMapper.deptAndEmpResultByStepTwo" column="did"> </collection> </resultMap> <select id="getDeptAndEmpByStepOne" resultMap="DeptAndEmpResultByStepMap"> select * from t_dept where did = #{did} </select>
第二步
mapper接口
public interface DeptMapper { // 分步获取部门以及部门中所有员工的信息 List<Emp> deptAndEmpResultByStepTwo(@Param("did") Integer did); }
mapper映射文件
<select id="deptAndEmpResultByStepTwo" resultType="Emp"> select * from t_emp where did = #{did} </select>