Mybatis学习(12)多表之延迟加载

本文深入探讨MyBatis中的延迟加载技术,包括直接加载、侵入式延迟加载及深度延迟加载三种策略,通过实例解释如何减少数据库压力,提高查询效率。

前言

什么是延迟加载?比较官方的意思是:在进行关联查询的时候,按照设置延迟规则推迟对关联对象的select查询。举一个例子。比如说我要查询一个订单的数据,但是我在查询订单的时候可能也会查这个订单的用户,但是如果我要用到这个订单用户信息的时候再去加载,此时也就是用户信息推迟一段时间加载。就用到了延迟加载技术。

那么延迟加载有什么好处呢?他可以有效地减少数据库的压力

一、延迟加载的时机

Mybatis根据对关联对象查询的select语句的执行时机,分为三种类型·:直接加载、侵入式延迟加载、深度延迟加载。

  1. 直接加载:执行完对主加载对象的select语句,马上执行对关联对象的select查询。
  2. 侵入式延迟加载:执行完对主加载对象的select语句,不会马上执行对关联对象的select查询。但是当要访问主加载对象的详情时候,就会马上执行关联对象select查询。可以这样理解,将关联对象的详情作为主加载对象的详情的一部分实现了。
  3. 深度延迟:执行完对主加载对象的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
直接加载falsefalse
深度延迟加载truetrue
侵入式延迟加载truetrue
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值