MyBatis延迟加载详解

本文详细探讨了MyBatis的延迟加载机制,包括Executor执行器与Handler的职责,开启延迟加载后Executor的query方法操作,以及何时触发延迟加载的数据使用。重点讲解了LazyLoader如何在调用get方法时通过缓存或数据库加载数据,同时阐述了EnhancedResultObjectProxyImpl代理对象在延迟加载中的关键作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前置知识

  1. Executor执行器负责将sql准备好并交给Handler

  1. Handler处理器分为几类,有专门负责sql执行的,有专门处理sql执行结果的

开启延迟加载会做什么

org.apache.ibatis.executor.statement.SimpleStatementHandler#query

看名字可以知道这个handler是专门执行sql的,通过statement执行完之后交给结果处理器来处理结果,追踪代码到核心处理方法里面后发现主要做了两件事,创建对象和赋值,赋值部分分为两种方式,自动映射和根据配置手动来映射,这些都在mapper文件中配置

org.apache.ibatis.executor.resultset.DefaultResultSetHandler#getRowValue(org.apache.ibatis.executor.resultset.ResultSetWrapper, org.apache.ibatis.mapping.ResultMap)

继续追踪,虽然分为了两个方法,但是这两个方法中都有一个核心方法如下图,红框处判断如果嵌套查询id不为0,就需要返回嵌套查询的值

org.apache.ibatis.executor.resultset.DefaultResultSetHandler#getPropertyMappingValue

接下来进入嵌套查询方法里面,具体如何查询的我们不管,重点看红框处,这里是个判断,如果有一级缓存,就调用加载方法deferLoad,如果没有的话,先判断下是否是懒加载,是的话就将数据放入一个loaderMap集合中,等待需要时使用

org.apache.ibatis.executor.resultset.DefaultResultSetHandler#getNestedQueryMappingValue

什么时候会使用延迟加载的数据

我们再回头看getRowValue这个方法,在映射前有一个createResultObject()方法,这个方法的主要作用就是创建一个代理对象,这个代理对象的作用就是在执行目标对象的get方法前需要先执行代理对象的代理方法, 这里的代理方法是EnhancedResultObjectProxyImpl的invoke方法

简单介绍下EnhancedResultObjectProxyImpl类,他是JavassistProxyFactory的一个静态内部类,他继承了MethodHandler接口,所有经过javassist代理的对象在执行get方法前都会先执行

在invoke方法中,我们可以看到真正调用延迟加载的地方,lazyLoader.load()方法主要做了两件事,如果缓存中有数据从缓存中获取,如果缓存中没有就从数据库中查

org.apache.ibatis.executor.loader.javassist.JavassistProxyFactory.EnhancedResultObjectProxyImpl#invoke

LazyLoader

延迟加载器,其中只有一个常量map集合,用来存放需要延迟加载的属性,key是属性名,value是一个静态内部类LoadPairLoadPair中包含一些sql语句、resultObject等信息,负责具体数据的获取工作。

org.apache.ibatis.executor.loader.ResultLoaderMap

总结

回顾一下延迟加载发生的事情,首先在查询时会先生成代理对象来对目标对象的get方法进行增强,然后在对对象属性赋值时判断是否是延迟加载,如果是延迟加载就把需要执行的sql以及其他数据存放到lazyLoader中的一个map表中,等待调用。

在真正使用即调用get方法时,代理对象会先执行invoke方法,从缓存或者数据库中获取懒加载数据,然后再返回数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值