延迟加载源码剖析:

  • 延迟加载
    就是在需要⽤到数据时才进⾏加载,不需要⽤到数据时就不加载数据。延迟加载也称懒加载。

  • 优点:
    先从单表查询,需要时再从关联表去关联查询,⼤⼤提⾼数据库性能,因为查询单表要⽐关联查询多张表速度要快。

  • 缺点:
    因为只有当需要⽤到数据时,才会进⾏数据库查询,这样在⼤批量数据查询时,因为查询⼯作也要消耗时间,所以可
    能造成⽤户等待时间变⻓,造成⽤户体验下降。

  • 在多表中:
    ⼀对多,多对多:通常情况下采⽤延迟加载
    ⼀对⼀(多对⼀):通常情况下采⽤⽴即加载

  • 注意:
    延迟加载是基于嵌套查询来实现的

  • 实现局部延迟加载
    在association和collection标签中都有⼀个fetchType属性,通过修改它的值,可以修改局部的加载策略。 fetchType=“lazy”

<!-- 开启⼀对多 延迟加载 -->
<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>
  • 全局延迟加载
    在Mybatis的核⼼配置⽂件中可以使⽤setting标签修改全局的加载策略。
<settings>
<!--开启全局延迟加载功能-->
	<setting name="lazyLoadingEnabled" value="true"/>
</settings>
  • 延迟加载原理实现
    它的原理是,使⽤ CGLIB 或 Javassist( 默认 ) 创建⽬标对象的代理对象。当调⽤代理对象的延迟加载属性的
    getting ⽅法时,进⼊拦截器⽅法。⽐如调⽤ a.getB().getName() ⽅法,进⼊拦截器的 invoke(…) ⽅法,
    发现 a.getB() 需要延迟加载时,那么就会单独发送事先保存好的查询关联 B 对象的 SQL ,把 B 查询上来,然后
    调⽤a.setB(b) ⽅法,于是 a 对象 b 属性就有值了,接着完成a.getB().getName() ⽅法的调⽤。这就是延迟
    加载的基本原理
    总结:延迟加载主要是通过动态代理的形式实现,通过代理拦截到指定⽅法,执⾏数据加载。

延迟加载原理(源码剖析)
MyBatis延迟加载主要使⽤:Javassist,Cglib实现,类图展示:
在这里插入图片描述
Setting 配置加载:
延迟加载代理对象创建
Mybatis的查询结果是由ResultSetHandler接⼝的handleResultSets()⽅法处理的。ResultSetHandler接⼝只有⼀
个实现,DefaultResultSetHandler,接下来看下延迟加载相关的⼀个核⼼的⽅法
默认采⽤javassistProxy进⾏代理对象的创建
//aggressive ⼀次加载性所有需要延迟加载属性或者包含触发延迟加载⽅法
if

通过invoke方法,判断调用的方法包含的属性数据是否配置开启了懒加载的字段,如果是通过代理对象再次load查询数据库,否则直接返回。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值