Rubin's Blog

  • 首页
  • 关于作者
  • 隐私政策
享受恬静与美好~~~
分享生活的点点滴滴~~~
  1. 首页
  2. MyBatis
  3. 正文

MyBatis之延迟加载

2021年 5月 13日 906点热度 0人点赞 0条评论

前言

顾名思义,延迟加载就是把加载的流程后置,从而提高系统的稳定性和可用性的一种手段。在前几篇关于MyBatis的博文中,我们详细阐述了MyBatis的使用方式以及原理。本博文主要针对一对多,多对多的场景下的延迟加载做一个详细描述。

MyBatis延迟加载

什么是延迟加载

在开发过程中很多时候我们并不需要总是在加载用户信息时就一定要加载他的订单信息。此时就是我们所说的延迟加载。就是在需要用到数据时才进行加载,不需要用到数据时就不加载数据。延迟加载也称懒加载。

优点

先从单表查询,需要时再从关联表去关联查询,大大提高数据库性能,因为查询单表要比关联查询多张表速度要快。

缺点

因为只有当需要用到数据时,才会进行数据库查询,这样在大批量数据查询时,因为查询工作也要消耗时间,所以可能造成用户等待时间变长,造成用户体验下降。

使用场景

  • 一对多,多对多:通常情况下采用延迟加载。
  • 一对一(多对一):通常情况下采用立即加载。

实现延迟加载

局部延迟加载

在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.rubin.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( 默认 ) 创建目标对象的代理对象。当调用代理对象的延迟加载属性的get方法时,进入拦截器方法。比如调用 a.getB().getName() 方法,进入拦截器的invoke(...) 方法,发现 a.getB() 需要延迟加载时,那么就会单独发送事先保存好的查询关联 B 对象的 SQL ,把 B 查询上来,然后调用 a.setB(b) 方法,于是 a 对象 b 属性就有值了,接着完成a.getB().getName() 方法的调用。这就是延迟加载的基本原理。

写在最后

由于源码比较多,本博文不在讲解源码实现过程。有兴趣的小伙伴可以自行查阅一下源码。这里给出一个源码实现延迟加载步骤,以方便大家阅读源码的时候有个方向:

  1. 查看解析XML的逻辑,会将全局的延迟加载配置封装进Configuration对象中,把局部延迟加载的配置封装进MappedStatement中。
  2. 延迟加载发生在解析查询结果的过程,需要关注ResultSetHandler的handleResultSets()方法,此方法中有关于延迟加载的实现逻辑。
本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: MyBatis
最后更新:2022年 6月 9日

RubinChu

一个快乐的小逗比~~~

打赏 点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复
文章目录
  • 前言
  • MyBatis延迟加载
    • 什么是延迟加载
      • 优点
      • 缺点
      • 使用场景
    • 实现延迟加载
      • 局部延迟加载
      • 全局延迟加载
    • 延迟加载的原理
  • 写在最后
最新 热点 随机
最新 热点 随机
问题记录之Chrome设置屏蔽Https禁止调用Http行为 问题记录之Mac设置软链接 问题记录之JDK8连接MySQL数据库失败 面试系列之自我介绍 面试总结 算法思维
MySQL之Sharding-JDBC分布式事务 MongoDB之架构设计 MySQL之Sharding-JDBC读写分离 MySQL之Sharding-JDBC强制路由 Docker之网络 SpringCloud Netflix之Ribbon负载均衡

COPYRIGHT © 2021 rubinchu.com. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

京ICP备19039146号-1