Mybatis框架学习笔记 --- [懒加载配置 应用到嵌套查询]

Posted 小智RE0

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mybatis框架学习笔记 --- [懒加载配置 应用到嵌套查询]相关的知识,希望对你有一定的参考价值。

mybatis官方文档–>mybatis在线文档

MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。 配置文档的顶层结构如下:
configuration(配置)
properties(属性)
settings(设置)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境配置)
environment(环境变量)
transactionManager(事务管理器)
dataSource(数据源)
databaseIdProvider(数据库厂商标识)
mappers(映射器)

懒加载

之前在关联查询时;
Mybatis框架学习笔记(4)—[resultMap 结果集映射配置 ; 多表关联SQL查询映射配置]

一次性就把需要的数据全部加载查询出来了;但是有时不需要这样;
比如说你要去查询得到某些关联信息;但是并不需要全部都一次取到;需要哪个信息才去加载查询一下;也就是说,需要将之前的一次性查询分解开来;分成嵌套查询

比如说;上次的根据Id查询员工信息;还关联了用户表来获取具体的操作人;关联部门表来获取具体的部门名称;

然后测试时,debug调试,一下就把员工的信息输出了


那么,如何让这个方法实现懒加载呢

当然首先得去核心配置文件 mybatis-config.xml 中配置;

lazyLoadingEnabledlazyLoadTriggerMethods

(1)配置开启懒加载

当然,我这个<settings>之中还有之前配置的日志,以及驼峰命名

<settings>
    <!--配置日志-->
    <setting name="logImpl" value="LOG4J"/>
    
    <!--设置开启驼峰命名匹配-->
    <setting name="mapUnderscoreToCamelCase" value="true"/>

    <!--配置延时加载-->
    <setting name="lazyLoadingEnabled" value="true"/>
    <setting name="lazyLoadTriggerMethods" value=""/>
</settings>

(2)定义方法

那么;为了和之前的区分一下;我就先去持久层接口重新定义个方法吧;(之前定义的方法先暂时去掉)
就在EmployeeMapper员工的持久层处理接口中定义方法;

public interface EmployeeMapper {
    //采用懒加载 根据Id查询员工;
    Employee getEmpByIdForLazy(Integer id);
}

(3)配置对应mapper中sql

该段来自官方文档


column:
数据库中的列名,或者是列的别名。一般情况下,这和传递给 resultSet.getString(columnName) 方法的参数一样。 注意:在使用复合主键的时候,可使用 column="{prop1=col1,prop2=col2}"这样的语法来指定多个传递给嵌套 Select 查询语句的列名。这会使得 prop1 和 prop2 作为参数对象,被设置为对应嵌套 Select 语句的参数。
select
用于加载复杂类型属性的映射语句的 ID,它会从 column 属性指定的列中检索数据,作为参数传递给目标 select 语句。 在使用复合主键的时候,可以使用 column="{prop1=col1,prop2=col2}"这样的语法来指定多个传递给嵌套 Select 查询语句的列名。这会使得 prop1 和 prop2 作为参数对象,被设置为对应嵌套 Select 语句的参数。
fetchType
可选的配置。可使用 lazy(懒加载) 和 eager(不用懒加载)。 指定属性后,将在映射中忽略全局配置参数 lazyLoadingEnabled,转而使用这个fetchType属性配置的值。

EmployeeMapper.xml中进行配置;
这时就要用到嵌套查询了;根据Id查询员工的信息拆分为 3 次执行的sql;
首先是根据Id查询得到员工的Id;姓名,性别以及 所在部门的Id 以及操作人Id;
然后;根据所在部门的Id查询部门的名称;
根据操作人的Id查询用户的姓名

<?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.xiaozhi.mapper.EmployeeMapper">
    <!--定义的 结果集映射2-->
    <resultMap id="empmap2" type="employee">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="sex" property="sex"/>
        <!--关联部门表  fetchType =lazy 使用延时加载 eager:不使用懒加载; 前提是嵌套查询 ,这里的select也就是对应下面的根据Id查询部门方法id-->
        <association property="dept" javaType="dept"  fetchType="lazy" select="getDeptById" column="deptID">
        </association>

        <!--关联用户管理表 select也就是对应下面的根据Id查询用户方法id -->
        <association property="user" javaType="user" fetchType="lazy" select="getUserById" column="optionId">
        </association>
    </resultMap>

    <!--实现懒加载 根据Id查询员工-->
    <select id="getEmpByIdForLazy" resultMap="empmap2">
        select `id`,`name`,`sex`,`deptID`,`optionId` from t_employee where id=#{id}
    </select>

    <!--根据Id查部门-->
    <select id="getDeptById" resultType="dept">
        select name from t_dept where id=#{deptID}
    </select>
    <!--根据Id查用户-->
    <select id="getUserById" resultType="user">
        select account from t_user where id=#{optionId}
    </select>
</mapper>

当然;别忘记在核心配置文件mybatis-config.xml中配置mapper映射文件的位置;

(4) 测试使用

//懒加载,根据Id查询员工;
 @Test
 public void getEmpByIdLazy(){
     //获取sqlSession
     SqlSession sqlSession = MyBatisUtils.getSqlSession();
     //获取代理对象;
     EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
     //根据ID查询员工;
     Employee emp = mapper.getEmpByIdForLazy(3);
     //控制台输出;
     System.out.println("员工姓名->"+emp.getName());
     System.out.println("部门名->"+emp.getDept().getName());
     System.out.println("管理员名->"+emp.getUser().getAccount());
     //关闭;
     sqlSession.close();
 }

先打个断点;debug调试
执行刚开始;并没有执行加载部门和用户的信息

控制台这边也仅仅是执行了根据Id查询员工的Id;姓名,性别以及 所在部门的Id 以及操作人Id;

然后向下调试;
需要执行输出这个员工的所在部门名称;
所以加载执行根据部门的Id查询部门的名称

看控制台这边的输出,也是执行到这一步

继续向下调试;
由于要获取操作人的姓名;
所以去根据用户的Id执行了查询

再看控制台这边

属性fetchType=“lazy” 与 fetchType=“eager” 的不同

懒加载算是基本模拟结束了;但是刚才也没有去为fetchType设置 值为"eager";
那么看看fetchType=“eager” 的效果

EmployeeMapper.xml中进行配置;

ok,就把根据操作人的Id查询用户这里设置为fetchType="eager"

还是刚才的测试调试代码;
打上断点;debug调试
诶;根据操作人Id查询用户这里直接就加载执行了;并没有延时懒加载

看控制台;这边也执行了

继续调试;
由于要得到部门的名称;
所以执行加载根据部门的ID查询部门的名称

继续调试;
这里控制台才根据需要输出打印操作人的名称信息

以上是关于Mybatis框架学习笔记 --- [懒加载配置 应用到嵌套查询]的主要内容,如果未能解决你的问题,请参考以下文章

Mybatis学习第25节 -- 懒加载 积极与不积极

Mybatis框架学习笔记

Mybatis框架学习笔记

MyBatis基础学习笔记--摘录

Mybatis懒加载机制

关于 Mybatis 设置懒加载无效的问题