MyBatis中有两个设置项和延迟加载有关:lazyLoadingEnable
和agressiveLazyLoading
。
前者可开启延迟加载,后者设为false
则是按需加载,两者配合使用。
Mybatis实现延迟加载的基本原理
MyBatis中的ResultMap关系映射中有两个标签:association
和collection
,前者适合一对一查询的关系映射,后者适合一对多查询的关系映射。
实现延迟加载也要用到它们。
假设我们使用测试方法测试延迟加载,先调用一个查询,查询得出结果赋给对象a
,里面包含未加载的null
值项,假设这一项为类B
的引用——b
,并且假设类B
拥有get方法getName()
。当我们调用a.getB().getName()
时,此时对象a
中的成员对象b
为null
,无法调用其的getName()
方法,此时Mybatis意识到要使用延迟加载来使此次调用不出Bug。
Mybatis使用CGLib生成目标对象a
的代理对象,当我们在测试方法里调用a.getB()
方法时,结果为null
,不可行。于是,Mybatis调用拦截器方法,使用事先在resultMap
中的association
或collection
标签里设定好的select
查询语句来获取数据库中的数据并映射到对象b
上,此时b
不再为null
,a.getB().getName()
顺利调用,实现了按需加载、延迟加载,节省了宝贵的计算资源。
百度百科CGLIB(Code Generation Library)
是一个开源项目。是一个强大的,高性能,高质量的代码生成类库,它可以在运行期扩展Java类与实现Java接口。Hibernate、MyBatis支持它来实现PO(Persistent Object 持久化对象)字节码的动态生成。