前言
什么是延迟加载?比较官方的意思是:在进行关联查询的时候,按照设置延迟规则推迟对关联对象的select查询。举一个例子。比如说我要查询一个订单的数据,但是我在查询订单的时候可能也会查这个订单的用户,但是如果我要用到这个订单用户信息的时候再去加载,此时也就是用户信息推迟一段时间加载。就用到了延迟加载技术。
那么延迟加载有什么好处呢?他可以有效地减少数据库的压力。
一、延迟加载的时机
Mybatis根据对关联对象查询的select语句的执行时机,分为三种类型·:直接加载、侵入式延迟加载、深度延迟加载。
- 直接加载:执行完对主加载对象的select语句,马上执行对关联对象的select查询。
- 侵入式延迟加载:执行完对主加载对象的select语句,不会马上执行对关联对象的select查询。但是当要访问主加载对象的详情时候,就会马上执行关联对象select查询。可以这样理解,将关联对象的详情作为主加载对象的详情的一部分实现了。
- 深度延迟:执行完对主加载对象的select语句,不会马上执行对关联对象的select查询。当要访问主加载对象的详情时候,也不会马上执行关联对象select查询。只有当真正访问关联对象的详情的时候,才会执行对关联对象的select查询。
注意:关联对象和主加载对象的查询必须是分别得select语句,不能是使用多表链接的select查询。因为,多表链接查询实际上就是对一张表的查询。
比如此例中:
<?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.test.dao.ICountryDao">
<select id="selectMinisterById" resultType="Minister">
select mid,mname
from minister
where
countryid=#{ooo}
</select>
<resultMap type="Country" id="countryMapper">
<id column="cid" property="cid"/>
<result column="cname" property="cname"/>
<collection
property="ministers"
ofType="Minister"
select="selectMinisterById"
column="cid"/>
</resultMap>
<select id="selectCountryById" resultMap="countryMapper">
select cid,cname
from country
where
cid = #{xxx}
</select>
</mapper>
二、直接加载
在这里我们使用的是一对多的关联查询

在mybatis.xml文件的<properties/>和<typeAliases/>标签之间,添加<setting/>标签,用于完成全局参数的设置。因为标签的书写位置,是定义好了的。

延迟加载的相关参数名称以及取值如下:

2.1 设置延迟加载
根据上图的说明:全局属性的lazyLoadingEnabled是延迟加载的一个总开关。当其值设置为false时候,那么将采用直接加载。

2.2 测试直接加载(设置断点可以查看效果)
修改测试类
@Test
public void testSelectCountryById() {
Country country=dao.selectCountryById(1);
System.out.println(country);
System.out.println(country.getCname());
System.out.println(country.getMinisters().size());
}
结果如下:

三、深度延迟加载
3.1设置深度延迟加载
修改主配置文件mybatis.xml文件

3.2测试(和直接加载一样代码不变)(设置断点可以查看效果)
此时,只有当代码需要输出Minister对象的详情的时候,底部才执行select语句。
四、侵入式延迟加载
4.1设置侵入式延迟加载

4.2测试(不变)

现在分析一下这个执行流程:
当执行到country.getCname时候,不会去查询minister表。但是当执行到下一个输出的时候,会立刻访问minister表。这是因为此时需要访问country的详情,但是minister的详情作为其一部分,此时需要用到minister,会立刻访问minister。
五、总结
| 加载策略 | lazyLoadingEnabled取值 | aggressiveLazyLoading |
| 直接加载 | false | false |
| 深度延迟加载 | true | true |
| 侵入式延迟加载 | true | true |
本文深入探讨MyBatis中的延迟加载技术,包括直接加载、侵入式延迟加载及深度延迟加载三种策略,通过实例解释如何减少数据库压力,提高查询效率。
7803

被折叠的 条评论
为什么被折叠?



