延迟加载
当使用<association>
进行嵌套查询时,如一个查询里嵌套着另一个表的查询。
默认情况下,会完整加载。即使那个表没有使用到,仍然会被查询。
可以通过<association>
的属性fetchType="lazy"
,和将Mybatis的全局配置为aggressiveLazyLoading=false
时,才会将按需加载。
如果,配置了
aggressiveLazyLoading=false
,而又需要在触发某些方法时,加载数据。 Mybatis提供了参数lazyLoadTriggerMethods
,默认值为equals()
,clone()
,hashCode()
,toString()
。可以通过调用其中的一个方法实现加载调用对象的数据。 例如:System.out.println("调用user.equals(null)"); user.equals(null); System.out.println("调用user.getRole()"); user.getRole();
这会出现2次查询,
equals()
触发了user表的查询。在调用getRoel()
时触发role表的查询。
error
莫名其妙的问题:为什么有些时候延迟加载可以得到数据,有时候延迟加载就会报错?
MyBatis延迟加载是通过动态代理
实现的,当调用配置为延迟加载的属性方法时,动态代理的操作会被触发,这些额外的操作就是通过MyBatis的SqlSession
去执行嵌套SQL的。
但由于在和某些框架集成时,SqlSession
的生命周期交给了框架来管理,因此当对象超出SqlSession
生命周期调用时,会由于链接关闭等问题而抛出异常。
在和Spring
集成时,要确保只能和Service
层调用延迟加载的属性。当结果从Service
层返回至Controller
层时,如果获取延迟加载的属性值,会因为SqlSession
已经关闭而抛出异常。