[mybatis] 延迟加载

 

延迟加载

当使用<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已经关闭而抛出异常。