延迟加载
延迟加载就是在需要某些数据的时候才去加载该数据。就上篇中的一对一、一对多查询中,如果我们只是需要员工信息用不着部门信息,这个时候就需要使用延迟查询,先查询员工的信息,后续有需要再去查询部门信息。
延迟加载配置
延迟加载需要在mybatis的全局配置文件中进行配置,因为延迟加载的配置设置会改变整个mybatis的运行行为,所以配置的时候根据情况具体分析。
设置参数 | 描述 | 有效值 | 默认值 |
---|---|---|---|
lazyLoadingEnabled | 延迟加载的全局开关。当开启时,多有的关联对象都会延迟加载。特定关联关系中可通过设置fetchType属性来覆盖该开关状态 | true/false | false |
aggressiveLazyLoading | 当开启时,任何方法的调用都会加载该对象的所有属性。否则,每个属性都会按需加载参考lazyLoadTriggerMethods | true/false | false |
在全局配置文件中进行设置:
<?xml version="1.0" encoding="UTF-8"?>
<!-- 这里的config表示这个配置文件是mybatis的整体配置文件 -->
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 配置数据库的参数从哪里读取 -->
<properties resource="db.properties"/>
<!-- 对MyBatis进行全局设置 -->
<settings>
<!-- 开启延迟加载 -->
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggerssiveLazyLoading" value="false"/>
</settings>
<!-- 设置数据类型别名 -->
<typeAliases>
<!-- 给指定的类设置别名 -->
<!-- <typeAlias type="com.xj.dao.User" alias="user"/> -->
<!-- 指定一个基础路径 使用直接调用名称不区分大小写 -->
<package name="com.xj.vo"/>
</typeAliases>
<!-- 数据库连接环境配置 -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!-- 连接映射配置 -->
<mappers>
<!-- 连接映射必须保证与调用接口名称一致 -->
<!-- <mapper resource="com/xj/dao/IUserdao.xml"/> -->
<!-- package 在接口的方式下使用,接口名称必须和映射文件名称一致 -->
<package name="com.xj.dao"/>
</mappers>
</configuration>
一对一的延迟加载
延迟加载需要写成两个SQL语句,分开查询。
映射配置文件代码:
<!-- 一对一延迟加载查询 -->
<resultMap type="user" id="delayMap">
<id column="no" property="no"/>
<result column="name" property="name"/>
<result column="age" property="age"/>
<!-- 在这里设置延时查询 -->
<association property="dept" javaType="Dept" column="deptno" select="queryDept">
<id column="deptno" property="deptno"/>
<result column="deptname" property="deptname"/>
<result column="deptdesc" property="deptdesc"/>
</association>
</resultMap>
<select id="queryDept" parameterType="int" resultType="dept">
select * from t_dept where deptno = #{deptno}
</select>
<select id="queryUser" resultMap="delayMap">
select * from t_user
</select>
测试代码及结果:
使用延迟加载:
List<User> list = mapper.queryUser();
for (User user : list) {
//调用了所有的参数用到了部门t_dept
System.err.println(user);
}
未使用延迟加载:
List<User> list = mapper.queryUser();
for (User user : list) {
//值调用了t_user的部分参数未使用t_dept参数
System.err.println(user.getName()+"--"+user.getAge());
}
一对多延迟加载
一对多延迟加载同上一对一加载,格式方法基本不变。
映射文件配置:
<!-- 一对多延迟加载查询 -->
<resultMap type="dept" id="delaydMap">
<id column="deptno" property="deptno"/>
<result column="deptname" property="deptname"/>
<result column="deptdesc" property="deptdesc"/>
<collection property="users" ofType="user" column="deptno" select="queryUserd">
<id column="no" property="no"/>
<result column="name" property="name"/>
<result column="age" property="age"/>
</collection>
</resultMap>
<select id="queryDeptd" resultMap="delaydMap">
select * from t_dept
</select>
<select id="queryUserd" parameterType="int" resultType="dept">
select * from t_user where deptno = #{deptno}
</select>
测试代码及结果:
使用延迟加载:
List<Dept> deptd = mapper.queryDeptd();
//调用所有参数,使用延迟加载
for (Dept dept : deptd) {
System.err.println(dept);
}
未使用延迟加载:
在这里List<Dept> deptd = mapper.queryDeptd();
//只使用t_dept的部分参数,不触发延迟加载
for (Dept dept : deptd) {
System.err.println(dept.getDeptno()+"---"+dept.getDeptname());
}插入代码片