MyBatis的延迟加载,你知道是怎么实现的么?


MyBatis的延迟加载,你知道是怎么实现的么?

文章插图
今天了不起来说说这个关于 MyBatis,为什么要说 Mybatis 呢?因为现在面试的时候,除了那些最基础的,比如如何防止 SQL 注入,以及 Mybatis 的一级缓存,二级缓存之后,还有一些其他的问题,比如 Mybatis 的延迟加载,并且需要说一下延迟加载的使用场景 。今天了不起就来给大家说一下这个延迟加载到底是怎么回事,以及延迟加载的使用场景 。
什么是延迟加载?延迟加载也称为懒加载、惰性加载,使用延迟加载可以提高程序的运行效率,针对数据持久层的操作,在某些特定查询的情况下去访问特定的数据库,在其他情况下可以不访问某些数据表,尽量减少 SQL 的执行,从而达到提高速度的目的,是对数据库操作的一种优化 。
什么情况下会出现延迟加载的情况我们来举个简单的例子
在一对多中,当我们有一个用户,它有个100个订单 在查询用户的时候,要不要把关联的订单查出来? 在查询订单的时候,要不要把关联的用户查出来?
那这个时候,答案就很清晰了,肯定要查出来的,但是,是我在需要的地方 。
在查询用户时,用户下的订单应该是,什么时候用,什么时候查询 。
在查询订单时,订单所属的用户信息应该是随着订单一起查询出来
这个时候我们就会用到延迟加载了,我用的时候,我们就查询,我们不用的时候,我们就不再继续的进行查询了 。
注意:延迟加载的应用要求:关联对象的查询与主加载对象的查询必须是分别进行的select语句,不能是使用多表连接所进行的select查询 。
延迟加载分类其实延迟加载也是有区分对的,而这个区分就是,全局的延迟加载和局部的延迟加载 。
全局延迟加载全局延迟加载的实现,实际上是通过修改配置文件来进行实现的,只要改了对应的配置配置文件,重启之后,肯定直接全局实现,所有需要用到全局加载的 xml 文件,都可以进行实现了 。
修改内容如下:
 【MyBatis的延迟加载,你知道是怎么实现的么?】<settings><!--开启全局延迟加载功能--><setting name="lazyLoadingEnabled" value=https://www.isolves.com/it/cxkf/jiagou/2023-04-28/"true"/>局部延迟加载在association和collection标签中都有?个fetchType属性,通过修改它的值,可以修改局部的加载策略 。
实现方式如下:
 <!-- 开启?对多 延迟加载 --><resultMap id="userMap" type="user"><id column="id" property="id"></id><result column="username" property="username"></result><result column="password" property="password"></result><result column="birthday" property="birthday"></result><!--fetchType="lazy" 懒加载策略fetchType="eager" ?即加载策略--><collection property="orderList" ofType="order" column="id"select="com.lagou.dao.OrderMApper.findByUid" fetchType="lazy"></collection></resultMap><select id="findAll" resultMap="userMap">SELECT * FROM `user`</select>其实在这里,我们需要注意一个内容,那就是延迟加载的时候:局部的加载策略的优先级高于全局的加载策略 。
这个也是面试的时候,经常会被问到的内容 。
那么我们就得来看看这个延迟加载的具体实现:
Spring配置加载 public class Configuration {/*** aggressiveLazyLoading:* 当开启时,任何?法的调?都会加载该对象的所有属性 。否则,每个属性会按需加载(参考lazyLoadTriggerMethods).* 默认为true*/protected boolean aggressiveLazyLoading;/*** 延迟加载触发?法*/protected Set<String> lazyLoadTriggerMethods = new HashSet<String>(Arrays.asList(new String[]{"equals", "clone", "hashCode", "toString" }));/*** 是否开启延迟加载*/protected boolean lazyLoadingEnabled = false;/*** 默认使?JAVAssist代理??** @param proxyFactory*/public void setProxyFactory(ProxyFactory proxyFactory) {if (proxyFactory == null) {proxyFactory = new JavassistProxyFactory();}this.proxyFactory = proxyFactory;}//省略...}Spring的加载,我们已经看到了,接下来我们还得看看延迟加载代理对象创建,他都是怎么来创建的,说到创建类,那么就得找到这个 ResultSetHandler 这个类了,内部是有有个 handleResultSets 的方法,而方法内部,就有加载的过程 。默认采用javassistProxy进行代理对象的创建


推荐阅读