目录
- 测试代码
- 调试代码
- 为什么BlogResp2是代理对象呢? 什么时候创建的代理对象呢? 让我们看一下源码
- 懒加载的赋值流程
- 懒加载失效的原因
- blogResp2的代理对象是如何构建lazyLoader属性的
- blogResp2的代理对象结构
测试代码
通过id 查询博客信息, 同时懒加载查询博客的所有评论信息
调试代码
可以看出, 现在的BlogResp2类型为一个代理对象
question : 为什么没有调用get方法就能查看到commentDOs的值呢?
因为idea自动给我们调用了toString()方法,
调用了这些方法, 都会给懒加载的值赋值
为什么BlogResp2是代理对象呢? 什么时候创建的代理对象呢? 让我们看一下源码
进入到63行
multipleResults为存储结果集对象的集合, 执行完194行发现, multipleResults中已经存在BlogResp2的代理对象, 进入194行
300 : 创建一个DefaultResultHandler
301 : 在这个方法中将结果集对象放入到defaultResultHandler的list属性中
302 : 获取到list, defaultResultHandler.getResultList(), 放入到multipleResults中
354 : rowValue 已经是blogResp2的代理对象
355 : 将rowValue存入到resultHandler的list属性中
进入354行
进入397行
635 : 判断是否有子查询, 并且子查询是否是懒加载
636 : 635为true, 则在636创建代理对象, 返回
代理对象创建完毕
懒加载的赋值流程
懒加载失效的原因
- 修改配置文件
<settings>
<!-- <setting name="cacheEnabled" value="true"></setting>-->
<!-- <setting name="lazyLoadingEnabled" value="false"></setting>-->
<!-- <setting name="lazyLoadingEnabled" value="true"/>-->
<!-- <setting name="aggressiveLazyLoading" value="false"/>--><setting name="lazyLoadingEnabled" value="true"/><setting name="aggressiveLazyLoading" value="false"/><setting name="lazyLoadTriggerMethods" value=""/></settings>
- 不要使用lombok提供的@Data注解, 一定要自己重写toString()方法
blogResp2的代理对象是如何构建lazyLoader属性的
396行 : 构建了一个ResultLoaderMap对象,
397行 : 构建bolgResp2的代理对象, 并将ResultLoaderMap作为属性传入
进入397行 :
636行 : 创建代理对象, 将lazyLoader值传入
进入636行
117行 : 将lazyLoader封装成EnhancedResultObjectProxyImpl类型对象
118行 ; 创建代理对象enhanced, 最后返回
大家可能会有疑问, 现在代理对象中的lazyLoader属性没有任何值, 懒加载是如何给lazyLoader赋值的呢?, 这就要说明一下, java有引用传递的概念, 先将空值的lazyLoader赋到代理对象中, 然后在修改lazyLoader的值, 让我们看一下在哪里修改的值
796行 : 为lazyLoader属性赋值
797行 : 为value赋一个默认值, 相当于一个标识符, 之后当判断value为DEFERED时, 就知道他是懒加载或者延迟加载
blogResp2的代理对象结构
接下来让我们执行一下get方法, 看一下源码的流程
143-144行 : 如果aggressive配置了true, 那么所有的懒加载都是被赋值, 不只有comments
145-147行 : 判断是不是set方法, 如果是, 则会覆盖懒加载的值
151行 : 进行懒加载
进入151行
79行 : 从map里面移除LoadPair, 说明懒加载只会进行一次
81行 : 进行懒加载
进入81行
219行 : 获取懒加载的值, 并赋值
70行 : 去执行查询数据库操作, list为查询数据库的结果
71行 : 将list转换, 赋值给resultObject, 最后返回
这就是全部的懒加载过程