Mybatis中的延迟加载,也叫做懒加载,是指在关联查询时,按照设置的延迟规则推迟对关联对象的select查询,延迟加载可以有效减少数据库的压力。
嵌套结果与嵌套查询
嵌套结果
在进行一对多的查询时一种类型的sql配置文件如下:
如上面的案例所示,在resultMap标签里面有collection标签,并且collection标签里面还有映射的内容,这种形式叫做嵌套结果。
嵌套查询
除了嵌套结果之外对应的还有嵌套查询,而嵌套查询与嵌套结果很类似,也是在一对多的查询时候用到,即resultMap标签里面也有collection标签,但是collection标签中没有结果集的一一映射,这种方式用在延迟加载中。
延迟加载的分类
直接加载
执行完对主加载对象的select语句,马上执行对关联对象的select查询。
在mybatis的主配置文件中配置
- 默认是false,也就是说如果使用默认值(也就是false),所有关联的sql都会查询出来。
一对一的直接加载
比如从订单的角度来看,订单和用户是一对一的关系,一对一可以通过association标签来体现,下面是一对一的直接加载案例。
OrdersMapper.xml
- association标签中的就是嵌套查询,因为该标签里面没有映射关系
- association标签中的property属性表示的是order这个po中的user对象属性
- association中的javaType属性表示的是返回值类型(这里使用user而不是全限定名是因为取了别名)
- select标签是关联用户的查询语句,这里是加载的另外一个mapper文件(UserMapper.xml文件)
- column属性表示是将哪一个参数值代入查询user的那个sql中,因为查询用户的sql中也是需要一个int类型作为参数,而column这个属性就是指定将orders中的uid这个属性值作为用户的查询条件。
- fetchType属性需要设置为lazy,也就是延迟加载。
用户的查询语句UserMapper.xml中
在执行ordersMapper.findOrdersById(int i)
;这个方法的时候不不仅仅会将orders表内容查询出来,还会将user表的内容也会查询出来,这种形式就是直接加载。
侵入式加载
执行对主加载对象的查询时,不会执行对关联对象的查询。但当要访问主加载对象的详情时,就会马上执行关联对象的select查询。即对关联对象的查询执行,侵入到了主加载对象的详情访问中。也可以这样理解:将关联对象的详情侵入到了主加载对象的详情中,即将关联对象的详情作为主加载对象的详情的一部分出现了。
在mybais主配置文件中配置
- 延迟加载开关需要开启,也就是lazyLoadingEnabled需要设置为true
- 侵入式延迟加载开关需要开启,也就是aggressiveLazyLoading需要设置为true
其余的sql配置文件相同,再来看一下测试代码:
@Test
public void findOrdersById () {
SqlSession sqlSession = sqlSessionFactory.openSession();
OrdersMapper ordersMapper = sqlSession.getMapper(OrdersMapper.class);
Orders orders = ordersMapper.findOrdersById(1);
//System.out.println(orders);
sqlSession.close();
}
如果将System.out.println(orders);这一句代码注释掉,那么只会查询orders这个表,因为没有使用到orders实体,但是如果将这句注释代码打开那么一开始就会既查询orders表也会查询user表,这就是侵入式的特点,因为使用到了orders表。
深度加载
执行对主加载对象的查询时,不会执行对关联对象的查询。访问主加载对象的详情时也不会执行关联对象的select查询。只有当真正访问关联对象的详情时,才会执行对关联对象的select查询
mybatis中的主配置文件
- 将延迟加载开关设置为true(默认是false,也就是直接加载)
- 将侵入式延迟加载设置为false(默认为true,也就是侵入式延迟加载),就会变成深度延迟加载。