MyBatis 延迟加载和立即加载
概念
我们设想一个场景,在用户-角色一对多的情况下,假如我们有一个用户,它有100个账户。在查询用户的时候要不要把关联的账户查询出来,在查询账户的时候要不要把关联的用户查询出来?
前者在内存中是这样的,用户对象里有账户列表的引用,这是非常大的开销,所以我们想用的时候查出来,不用的时候不查出来
所以我们得尽量在查询用户时,用户下的账户信息应该是,什么时候用,什么时候查询出来,这称为延迟加载。
对于后者,通常情况下在查询账户时,账户的所属用户信息应随着账户查询时一起查询出来,对于每条账户,这是一对一关系,不会开销大,这成为立即加载。
延迟加载就是在真正使用数据时才发起查询,不用的时候不查询,按需加载,也成为懒加载。
立即加载就是不管用不用,只要一调用方法,马上发起查询。
一对一实现延迟加载
我们新建个工程,沿用one2many工程的代码,起名叫01lazy
这条sql语句只要执行,一执行就是查两张表,也就没有延迟加载的实现,而是实现了立即加载
所以为了实现延迟加载,我们需要在xml配置里改一改,我们在关联属性association里加入一个新属性select
实现了这个配置,我们需要知道,延迟加载是有开关的
以及一个是否按强加载的开关
我们要在sqlMapConfig里对这两个开关进行配置,因为我们的mybatis版本是3.4.5,第二个开关的默认值是false,是不用配置的,这里我们都配上
最后我们改一下方法的sql语句
然后我们来跑一下findall方法,可以看到user的属性是一个一个查出来的
如果我只执行个findall
我们就会发现不会对user属性进行查询,也就实现了延迟加载,做到了要用的时候才查
一对多实现延迟加载
我们IUserDao的配置里可以看到,用这条sql语句是无法进行延迟加载的,因为在查表的时候左外连接一下直接就全部查出来了
现在我们把他改成只查user表
然后我们更改collection配置,和上面一样column的值是select属性查询方法的参数
然后我们在IAccountDao里加个方法
完成该方法的配置
最后我们运行一下我们的测试类,可以看到成功实现了延迟加载