mybatis 06 映射体系 02

  1. 懒加载的使用
  2. 懒加载底层探究

懒加载的使用

懒加载机制可以提升程序的性能

配置懒加载

如果我们要给blog的comments配置懒加载,需要在resultMap中配置启用懒加载

那么,懒加载何时触发呢?

  • 调用toString()
  • 调用hashCode()
  • 调用被设置懒加载的属性:
    上面的例子中,blog.getComments()会触发comments的懒加载,如果你使用了下文提到的全局开关aggressiveLazyLoading,调用其他get方法也会触发commnets的懒加载

划重点:编译器debug的时候会自动调用toString(),因此你会发现已经懒加载

全局配置方案

  • 全局懒加载开关,默认false
  • 调用任意方法触发懒加载,默认true

懒加载底层探究

若要实现对一个实现类的动态代理,基于java原生动态代理是不行的。我们可以通过cglib或javaassist来实现,mybatis的懒加载底层就是基于javaassist

arthas

我们现在用阿里开源工具arthas来研究下懒加载

先下载:https://alibaba.github.io/arthas/arthas-boot.jar

其他帮助参考官网:https://alibaba.github.io/arthas/

编写测试程序

在测试程序中,我们需要打印类名称,加入最后一句代码,避免程序退出

运行main方法,此时控制台打印了动态代理后的blog的类名称

启动arthas:

java -jar arthas-boot.jar //如果不行用下面这句
java -jar arthas-boot.jar --telnet-port 9998 --http-port -1

找到我们的main方法,然后在控制台输入索引

稍等片刻,我们进入了新的控制台

控制台输入: jad 上面控制台打印了动态代理后的blog的类名称

此时,arthas帮我们生成了这个类的内容,拷贝内容到txt中查看

当外部调用blog.getCommnets()时,程序会触发handler逻辑,考虑到性能优化,程序会判断是否懒加载过

下面,我们追踪下成员变量MethodHandler

很可惜,这里线索已经断

我们现在回过来看看:是在哪里创建了这个Blog动态代理呢?

从ResultSetHandler入手,找到其实现类DefaultResultSetHandler,可以看到底层通过这几句代码创建了其代理类

从《mybatis 06 映射体系 01》了解到嵌套子查询的关键方法DefaultResultSetHandler.getNestedQueryMappingValue(),里面会处理懒加载逻辑,我们继续查看这块代码:

  • 传入ResultLoaderMap
  • 生成ResultLoader
  • 放入ResultLoaderMap中,key是懒加载的属性名称

当我们调用getComments()方法时,会触发懒加载,ResultLoader#loadResult方法。

基于这种机制,如果在懒加载之前,我们把sqlsession关闭掉,会如何?

不受影响!看上图黄色框代码,证明:

如果跨线程了或者执行器(sqlsession)已经被关闭了,它会执行实例化


转载请注明来源。 欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。 可以在下面评论区评论,也可以邮件至 sharlot2050@foxmail.com。

文章标题:mybatis 06 映射体系 02

字数:704

本文作者:夏来风

发布时间:2020-06-14, 10:10:19

原始链接:http://www.demo1024.com/blog/mybatis-06-mapping-02/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。