当前位置: 首页 > news >正文

MyBatis 延迟加载使用及原理 - Higurashi

一、延迟加载是什么?

延迟加载(Lazy Loading)又称“惰性加载”,指的是:

当查询一个对象时,不立即加载它的关联对象(如一对多、多对一关系),而是在第一次真正使用该关联对象时才去执行 SQL 查询加载它。

举个例子:

User user = userMapper.selectById(1);
// 此时只查了 user 表,不查 order 表
user.getOrders(); // 这一步才去执行查询 orders 的 SQL

这样可以避免一次性加载大量无关数据,提高查询性能。

二、如何开启延迟加载?

在 MyBatis 的mybatis-config.xml中配置:

<settings><!-- 全局启用延迟加载 --><setting name="lazyLoadingEnabled" value="true"/><!-- 设置为 true 时,所有关联对象都会延迟加载 --><setting name="aggressiveLazyLoading" value="false"/>
</settings>

aggressiveLazyLoading:

  • true(旧版本默认):访问任意属性时会触发所有懒加载属性;
  • false:只在访问对应属性时才加载(推荐,性能更好)。

然后在映射文件中配置关联关系:

<resultMap id="userMap" type="User"><id property="id" column="id"/><result property="name" column="name"/><collection property="orders"select="selectOrdersByUserId"column="id"/>
</resultMap>

此时,当访问user.getOrders()时,才会触发对Order的查询。

lazyLoadingEnabled配置是全局开关,也可以在单个映射关系上通过属性fetchType="lazy"来开启懒加载:

<resultMap id="userMap" type="User"><id property="id" column="id"/><result property="name" column="name"/><collection property="orders"fetchType="lazy"select="selectOrdersByUserId"column="id"/>
</resultMap>

三、实现原理(源码层面)

延迟加载的核心为动态代理机制。

查询阶段:创建代理对象

MyBatis 在查询阶段会扫描每个ResultMap的映射字段,判断哪些字段需要懒加载,然后为结果对象创建代理。

DefaultResultSetHandler.handleResultSets()里,MyBatis 读取 ResultSet 时会调用getRowValue()

image-20251014223608719

这个方法会为每一行创建 Java 对象(例如User),并填充属性。注意其中的createResultObject方法和applyPropertyMappings方法,createResultObject创建了结果对象的动态代理对象:

image-20251014223948757
image-20251014224044696
image-20251014224109591

注意createResultObject方法接收lazyLoader作为参数,此时lazyLoader内部是个空集合。

下一步applyPropertyMappings方法才在lazyLoader中添加用于加载不同属性(可能有多个关联属性)的ResultLoader

image-20251015000829613
image-20251015000855780
image-20251015001014696

这样返回的user实际上是一个代理对象,它的某些属性还没被真正赋值。

访问阶段:触发加载

当我们在 Java 代码中第一次调用:

user.getOrders();

其方法被代理,代理逻辑封装在EnhancedResultObjectProxyImpl,其intercept方法中,使用ResultLoaderMap lazyLoader加载了 Getter 方法所获取的属性:

image-20251014235416401

ResultLoaderMap#load最终通过ResultLoader#loadResult加载属性值:

image-20251014235619013
image-20251014235641346
image-20251014235804055

ResultLoader#loadResult通过Executor查询到结果:

image-20251015000204849

这样,数据就在真正访问时被加载。

http://www.sczhlp.com/news/195902/

相关文章:

  • 中石化两学一做网站在线做网站流程
  • 学校网站怎么下载不了做erp系统的网站
  • 怎么看是哪家做的网站做网络推广怎么找客户
  • 想建个企业网站非遗文化网站建设
  • 做网站软件是什么行业wordpress js 添加图片
  • 传统网站有没有建设必要性wordpress文章全部展示
  • 成都企业网站维护wordpress小论坛小程序
  • dw 做网站模板中国建设官网招聘网站
  • 泉州优化seo网站关键词优化建站工具箱接线图
  • 南梁红色景区建设管理局网站wordpress数据库命名
  • 陕西建设厅人才网站Wordpress手机短信
  • 网站开发流程知乎锐速做网站
  • 建设电脑网站wordpress贴内幻灯片
  • 好玩有趣的网站没有网站百度推广
  • 廊坊网站优化淄博抖音推广公司
  • 南充网站建设略奥网络阳江市问政平台留言
  • 做网站一般收取多少钱wordpress编辑角色无法上传图片
  • 制作网站的公司2017优秀网站设计
  • 网站服务器租用怎么购买免费软件大全app下载
  • 邯郸做网络推广的公司南京seo网站管理
  • Mac怎么搭建网站开发环境哈尔滨企业网站建站推荐
  • 莆田网站自助建站个人网站备注模板
  • 网页设计与网站建设ppt仿珠宝首饰网站开发
  • 住房和城乡建设部网站规范答疑设计制作我们的小船
  • 企业网站备案网址泰安seo
  • html免费网站模板下载网站开发专业定制
  • 互动力 网站建设做一个平台网站大概多少钱
  • 内网穿透进阶:让 frpc 只代理「真正在线」的端口
  • 规则逻辑与人文逻辑的统一:AI元人文构想的演进之路
  • 2023 ICPC Jinan