MyBatis测试resultMap,分步查询以及延迟加载

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MyBatis测试resultMap,分步查询以及延迟加载相关的知识,希望对你有一定的参考价值。

什么是resultMap?

  resultMap即自定义结果集映射规则,之前我们使用的resultType是MyBatis为我们提供的默认映射规则,使用方法如下:

<mapper namespace="com.zgz.MyBatis.dao.DeptMapper">
        <select id="getDeptById" resultType="com.zgz.MyBatis.bean.Dept">
            select id, dept_name deptName from tbl_dept where id = #{id}
        </select>
</mapper>

  那么resultMap的作用是什么呢?之前我们在处理数据库中字段与javabean中的属性不一致的问题时,采用的方法是起别名或者开启mybatis的自动驼峰映射,现在可以使用resultMap来做,另外可以使用解决级联查询的问题

如何使用resultMap?

 我们现在新建一张员工部门表,要求是在我们查询员工的同时查询出员工对应的部门?
首先给出对应的JavaBean

public class Dept {
    private Integer id;
    private String deptName;
    //get,set,tostring()。。。

}

写上相应的mapper

<mapper namespace="com.zgz.MyBatis.dao.DeptMapper">
        <select id="getDeptById" resultType="com.zgz.MyBatis.bean.Dept">
            select id, dept_name deptName from tbl_dept where id = #{id}
        </select>
</mapper>

SQL映射文件中进行配置:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zgz.MyBatis.dao.EmployeeMapperPlus">

    <!-- 
        测试resultMap(自定义某个javabean的封装规则)
        type:自定义规则的java类型
        id:方便引用,唯一 
    -->
    <resultMap type="com.zgz.MyBatis.bean.Employee" id="MyEmp">
        <!-- 
            id:指定主键的封装规则,底层会有优化
                column:指定哪一列
                property:指定对应的javabean属性 
        -->
        <id column="id" property="id"/>
        <!-- result是指定普通列的封装规则 -->
        <result column="last_name" property="lastName"/>
        <!-- 其他的不指定会默认封装,最好指定一下 -->
        <result column="email" property="email"/>
        <result column="gender" property="gender"/>
    </resultMap>

    <!-- resultMap:自定义结果集映射规则 -->
    <select id="getEmployeeByGender" resultMap="MyEmp">
        select * from tbl_employee where gender = #{gender}
    </select>

    <!-- resultMap级联查询 -->
    <!-- 第一种方法:使用级联属性封装结果集-->
    <resultMap type="com.zgz.MyBatis.bean.Employee" id="MySecond">
        <id column="id" property="id"/>
        <result column="last_name" property="lastName"/>
        <result column="gender" property="gender"/>
        <result column="email" property="email"/>

        <result column="did" property="dept.id"/>
        <result column="dept_name" property="dept.deptName"/>
    </resultMap>
    <!-- 第二种方法: 使用association定义单个对象的封装 -->
    <resultMap type="com.zgz.MyBatis.bean.Employee" id="MyThird">
        <id column="id" property="id"/>
        <result column="last_name" property="lastName"/>
        <result column="gender" property="gender"/>
        <result column="email" property="email"/>

        <!--
            association:可以指定联合的javabean对象
                property:指定哪个属性是联合的对象
                javaType:指定这个属性的类型(不能省略)    
        -->
        <association property="dept" javaType="com.zgz.MyBatis.bean.Dept">
            <id column="did" property="id"/>
            <result column="dept_name" property="deptName"/>
        </association>      
    </resultMap>
    <!-- 第三种方法:分步查询 -->
    <resultMap type="com.zgz.MyBatis.bean.Employee" id="MyFourth">
        <id column="id" property="id"/>
        <result column="last_name" property="lastName"/>
        <result column="gender" property="gender"/>
        <result column="email" property="email"/>

        <!-- 
            使用 association 进行分步查询:
                1. 先按照员工id查询员工信息
                2. 根据查询到的员工信息的d_id值去查出部门信息
                3. 部门设置到员工里面
            association 定义关联对象的封装规则
                select:表明当前属性是调用select指定的方法查出的结果
                column:指定将哪一列的值传给这个方法
            流程:(理解)
                使用select制定的方法,传入column指定的这列参数的值查出对象,并封装给property指定的属性
        -->
        <association property="dept" 
            select="com.zgz.MyBatis.dao.DeptMapper.getDeptById" column="d_id">
        </association>
    </resultMap>

    <!-- 场景一:查询员工的同时查询出员工对应的部门 -->
    <select id="getEmpAndDept" resultMap="MyThird">
        SELECT e.id id, e.last_name last_name,e.email email, e.gender gender, e.d_id d_id, d.id did, d.dept_name dept_name
        FROM tbl_employee e, tbl_dept d 
        WHERE e.d_id = d.id AND e.id = #{id}
    </select>

    <!-- 分步查询 -->
    <select id="getEmpByIdStep" resultMap="MyFourth">
        select * from tbl_employee where id = #{id}
    </select>
    <!-- 
        分步查询可以使用延迟加载(按需加载)(懒加载):
            Employee ===》 Dept
                要查询Dept,我们每次查询Employee时都将一起查询出来
                为了达到部门信息在我们使用的时候在查询出来的要求,我们可以在分步查询的基础上加两个配置(在mybatis中的主配置文件中)
     -->

</mapper>

主配置文件中配置:

<configuration>

    <!-- configuration里的标签必须按顺序写 -->
    <settings>
        <!--  显示我们需要更改配置的值,即使是默认的建议写上,防止版本更新带来的问题 -->
        <setting name="lazyLoadingEnabled" value="true"/>
        <setting name="aggressiveLazyLoading" value="false"/>
    </settings> 

    <environments default="development">
        <environment id="test">
            <transactionManager type=""></transactionManager>
            <dataSource type=""></dataSource>
        </environment>

        <environment id="development">
            <transactionManager type="JDBC" />
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url"
                    value="jdbc:mysql://localhost:3306/mybatis?useSSL=false" />
                <property name="username" value="root" />
                <property name="password" value="123456" />
            </dataSource>
        </environment>
    </environments>

    <!-- 将我们写好的sql映射文件(testEmployeeMapper.xml)注册到全局配置文件(mybatis-config.xml)中 -->
    <mappers>
        <mapper resource="testEmployeeMapperPlus.xml" />
        <mapper resource="testDeptMapper.xml" />
    </mappers>
</configuration>

注意事项(填了好长时间的坑)

 1》千万不要忘记将我们写好的sql映射文件注册到全局配置文件中,注意是所有的sql映射文件

<mappers>
        <mapper resource="testEmployeeMapperPlus.xml" />
        <mapper resource="testDeptMapper.xml" />
    </mappers>

 2》configuration里的标签必须按顺序写,标签是有顺序的
技术分享图片

以上是关于MyBatis测试resultMap,分步查询以及延迟加载的主要内容,如果未能解决你的问题,请参考以下文章

MyBatis自定义映射resultMap

MyBatis自定义映射resultMap

mybatis入门篇2 --- mybatis的部分配置信息以及连表查询,分步查询

resultMap2_关联查询collection分步查询&延迟加载

Mybatis:resultMap的使用总结

Mybatis的mapper文件中#和$的区别 以及 resultType和resultMap的区别