自定义映射resultMap和延迟加载

自定义映射resultMap:

resultMap处理字段和属性的映射关系

  • resultMap:设置自定义映射关系
    • 属性:
      • id:表示自定义映射的唯一标识,不能重复
      • type:查询的数据要映射的实体类的类型
    • 子标签:
      • id:设置主键的映射关系
      • result:设置普通字段的映射关系
      • 子标签属性:
        • property:设置映射关系中的属性名,必须是type属性所设置的实体类类型中的属性名
        • column:设置映射关系中的字段名,必须是SQL语句查询出来的字段名
  • –》若字段名和实体类中的属性名不一致,可以通过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>
  • –》若字段名和实体类中的属性名不一致,因为字段名符合数据库的规则(使用 _ ),实体类中的属性名符合Java的规则(使用 驼峰 )。此时也可通过以下两种方式处理字段名和实体类中的属性的映射关系

    1、可以通过为字段起别名的方式,保证和实体类中的属性名保持一致

    <!--List<Emp> getAllEmp();-->
    <select id="getAllEmp" resultType="Emp">
    	select eid,emp_name empName,age,sex,email from t_emp
    </select>
    

    2、可以在MyBatis的核心配置文件中的setting标签中,设置一个全局配置信息mapUnderscoreToCamelCase,可以在查询表中数据时,自动将_类型的字段名转换为驼峰,例如:字段名user_name,设置了mapUnderscoreToCamelCase,此时字段名就会转换为userName。

    <settings>
     	<setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
    

多对一映射处理:

查询员工信息以及员工所对应的部门信息

public class Emp {  
	private Integer eid;  
	private String empName;  
	private Integer age;  
	private String sex;  
	private String email;  
	private Dept dept;
	//...构造器、get、set方法、toString方法等
}

处理多对一映射关系的方式一:级联属性赋值

<resultMap id="empAndDeptResultMapOne" 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 getEmpAndDept(@Param("eid")Integer eid);-->
<select id="getEmpAndDept" resultMap="empAndDeptResultMapOne">
	select * from t_emp left join t_dept on t_emp.eid = t_dept.did where t_emp.eid = #{eid}
</select>

处理多对一映射关系的方式二:association标签

  • association:处理多对一的映射关系
  • property:需要处理多对一映射关系的属性名
  • javaType:该属性的类型
<resultMap id="empAndDeptResultMapTwo" 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 getEmpAndDept(@Param("eid")Integer eid);-->
<select id="getEmpAndDept" resultMap="empAndDeptResultMapTwo">
	select * from t_emp left join t_dept on t_emp.eid = t_dept.did where t_emp.eid = #{eid}
</select>

处理多对一映射关系的方式三:分步查询

分步查询第一步. 查询员工信息
// EmpMapper.xml里的方法
/**
 * 通过分步查询,查询员工以及员工所对应的部门信息
 * 分步查询第一步:查询员工信息
 */
Emp getEmpAndDeptByStepOne(@Param("eid") Integer eid);
<resultMap id="empAndDeptByStepResultMap" 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>
    <!--
            select:设置分步查询的sql的唯一标识(namespace.SQLId或mapper接口的全类名.方法名)
            column:设置分步查询的条件
          -->
    <association property="dept"
                 select="com.atguigu.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwo"
                 column="did"></association>
</resultMap>
    
<select id="getEmpAndDeptByStepOne" resultMap="empAndDeptByStepResultMap">
    select * from t_emp where eid = #{eid}
</select>
分步查询第一步. 查询部门信息
//DeptMapper里的方法
/**
 * 通过分步查询,查询员工以及员工所对应的部门信息
 * 分步查询第二步:通过did查询员工所对应的部门
 */
Dept getEmpAndDeptByStepTwo(@Param("did") Integer did);
<!--此处的resultMap仅仅是处理字段(dept_name)和属性(deptName)的映射关系-->
<resultMap id="EmpAndDeptByStepTwoResultMap" type="Dept">
	<id property="did" column="did"></id>
	<result property="deptName" column="dept_name"></result>
</resultMap>

<!--Dept getEmpAndDeptByStepTwo(@Param("did") Integer did);-->
<select id="getEmpAndDeptByStepTwo" resultMap="EmpAndDeptByStepTwoResultMap">
	select * from t_dept where did = #{did}
</select>

一对多映射处理:

public class Dept {
    private Integer did;
    private String deptName;
    private List<Emp> emps; 
	//...构造器、get、set方法等
}

通过collection标签解决一对多的映射关系:

  • collection:用于处理一对多的映射关系
  • ofType:表示该属性对应的集合中存储数据的类型(就是上方List emps定义的集合的类型)
<resultMap id="DeptAndEmpResultMap" type="Dept">
	<id property="did" column="did"></id>
	<result property="deptName" column="dept_name"></result>
    <!-- 
   		collection:处理一对多的映射关系
        ofType:表示该属性所对应的集合中存储数据的类型
 -->
	<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 getDeptAndEmp(@Param("did") Integer did);-->
<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>

通过分步查询解决一对多的映射关系:

1. 根据部门id查询部门信息
/**
  * 通过分步查询 查询部门以及部门中所有的员工信息
  * 分步查询第一步:查询部门信息
 */
Dept getDeptAndEmpByStepOne(@Param("did") Integer did);
<resultMap id="DeptAndEmpByStepOneResultMap" type="Dept">
	<id property="did" column="did"></id>
	<result property="deptName" column="dept_name"></result>
    <!--
		 select:设置分步查询的sql的唯一标识(namespace.SQLId或mapper接口的全类名.方法名)
         column:设置分步查询的条件
	-->
	<collection property="emps"
				select="com.atguigu.mybatis.mapper.EmpMapper.getDeptAndEmpByStepTwo"
				column="did"></collection>
</resultMap>

<!--Dept getDeptAndEmpByStepOne(@Param("did") Integer did);-->
<select id="getDeptAndEmpByStepOne" resultMap="DeptAndEmpByStepOneResultMap">
	select * from t_dept where did = #{did}
</select>
2. 根据部门id查询部门中的所有员工
/**
  * 通过分步查询 查询部门以及部门中所有的员工信息
  * 分步查询第二步:根据did查询员工信息
  * 类型定义为:List<Emp> 是因为在Dept的model类中定义的emps的类型就是这个
 */
List<Emp> getDeptAndEmpByStepTwo(@Param("did") Integer did);
<!--List<Emp> getDeptAndEmpByStepTwo(@Param("did") Integer did);-->
<select id="getDeptAndEmpByStepTwo" resultType="Emp">
	select * from t_emp where did = #{did}
</select>

总结:

多对一:对应对象!(需要在实体类中创建"一"的对象,就相当于上方在Emp类中创建Dept对象)!

一对多:对应集合!(需要在实体类中创建存储"多"的集合,就相当于上方在Dept类中创建List集合)!

延迟加载:

  • 分步查询的优点:可以实现延迟加载,但是必须在核心配置文件中设置全局配置信息:
    • lazyLoadingEnabled:延迟加载的全局开关。当开启时,所有关联对象都会延迟加载
    • aggressiveLazyLoading:当开启时,任何方法的调用都会加载该对象的所有属性。 否则,每个属性会按需加载
  • 此时就可以实现按需加载,获取的数据是什么,就只会执行相应的sql。此时可通过association和collection中的fetchType属性设置当前的分步查询是否使用延迟加载(使延迟加载可控),fetchType=“lazy(延迟加载(默认))|eager(立即加载)”
<!--核心配置文件(mybatis-config.xml)-->
<settings>
	<!--开启延迟加载,这样在Mybatis范围内全部都实现延迟加载!-->
	<setting name="lazyLoadingEnabled" value="true"/>
</settings>
@Test
public void getEmpAndDeptByStepOne() {
	SqlSession sqlSession = SqlSessionUtils.getSqlSession();
	EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
	Emp emp = mapper.getEmpAndDeptByStepOne(1);
	System.out.println(emp.getEmpName()); // 只获取员工姓名!
}
  • 关闭延迟加载,两条SQL语句都运行了
    在这里插入图片描述
  • 开启延迟加载,只运行获取emp的SQL语句 在这里插入图片描述
@Test
public void getEmpAndDeptByStepOne() {
	SqlSession sqlSession = SqlSessionUtils.getSqlSession();
	EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
	Emp emp = mapper.getEmpAndDeptByStepOne(1);
	System.out.println(emp.getEmpName());
	System.out.println("----------------");
	System.out.println(emp.getDept());
}
  • 关闭延迟加载:
    在这里插入图片描述

  • 开启后,需要用到查询dept的时候才会调用相应的SQL语句
    在这里插入图片描述

<resultMap id="empAndDeptByStepResultMap" 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>
    <!-- 
 		fetchType:当开启了全局的延迟加载之后(必须要先开启全局延迟加载,否则下面的两个属性都是立即加载的意思),可以通过该属性手动控制延迟加载的效果.
		fetchType="lazy(延迟加载(默认))|eager(立即加载)"
	-->
	<association property="dept"
				 select="com.atguigu.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwo"
				 column="did"
				 fetchType="lazy"></association>
</resultMap>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MybatisPlus是一个基于Mybatis框架的增强工具,可以简化和加速开发过程。在使用MybatisPlus进行数据库操作时,我们可以利用它自带的功能来进行基本的CRUD操作,同时也可以进行自定义映射resultmap自定义映射resultmap可以帮助我们在数据库查询结果与实体类之间建立映射关系,进而方便地操作数据。一般情况下,MybatisPlus会根据数据库字段与实体类属性的对应关系自动进行映射,但在某些特殊情况下,我们可能需要自己来定义映射关系。 要自定义映射resultmap,我们可以通过在实体类中使用注解`@ResultMap`来实现。首先,我们需要在实体类中定义与数据库字段对应的属性,并通过注解`@TableField`来指定数据库字段名。然后,我们可以在实体类中使用注解`@ResultMap`来声明自定义映射resultmap,并指定与数据库字段对应的属性。 例如,有一个数据库表student,包含字段id、name和age,我们可以定义一个实体类Student,其中id属性对应数据库字段id,name属性对应数据库字段name,age属性对应数据库字段age。然后,在Student类中使用注解`@ResultMap`自定义映射resultmap,例如: ```java @Data public class Student { @TableField("id") private Long id; @TableField("name") private String name; @TableField("age") private Integer age; @ResultMap("studentResultMap") public class StudentResultMap{ return new StudentResultMap(){ put("id", "id"); put("name","name"); put("age","age"); } } } ``` 在上述示例中,我们定义了一个名为studentResultMap自定义映射resultmap,并通过`put`方法指定了属性与数据库字段的对应关系。 当我们需要进行数据库查询时,可以通过`@Select`注解或者使用MybatisPlus提供的查询方法来执行查询操作。在查询操作中,我们可以使用自定义映射resultmap来获取查询结果,并将其映射到实体类中。 总之,通过自定义映射resultmap,我们可以灵活地实现数据库查询结果与实体类的映射关系,提高了系统的可维护性和代码的可读性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值