1.1 什么是延迟加载
延迟加载又称为懒加载,按需加载。每次只查询1张表,当需要另一张关联表中的数据的时候,再发送一条SQL语句去查询另一张表中数据。
案例说明
* 在一对多中,当我们有一个用户,它有个100个订单
在查询用户的时候,要不要把关联的订单查出来?
在查询订单的时候,要不要把关联的用户查出来?
* 回答
在查询用户时,用户下的订单应该是,什么时候用,什么时候查询。
在查询订单时,订单所属的用户信息应该是随着订单一起查询出来。
延迟加载特点
优点:
先从单表查询,需要时再从关联表去关联查询,大大提高数据库性能,因为查询单表要比关联查询多张表速度要快。
缺点:
因为只有当需要用到数据时,才会进行数据库查询,这样在大批量数据查询时,因为查询工作也要消耗时间,所以可能造成用户等待时间变长,造成用户体验下降。
注意点:
- 在多表中:一对多,多对多:通常情况下采用延迟加载, 一对一(多对一):通常情况下采用立即加载。
- 延迟加载是基于嵌套查询来实现的。
12.2 项目目录
12.3 实现延迟加载
局部延迟加载
在association和collection标签中都有一个fetchType属性,通过修改它的值,可以修改局部的加载策略。
UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 实体类接口的类全名 -->
<mapper namespace="cn.guardwhy.dao.UserMapper">
<!--2.1映射主键-->
<!-- 开启一对多 延迟加载 -->
<resultMap id="userMap2" type="user">
<id column="id" property="id"></id>
<result column="user_name" property="username"></result>
<result column="birthday" property="birthday"></result>
<result column="sex" property="sex"></result>
<result column="address" property="address"></result>
<!--根据用户Id,查询订单表-->
<!--
fetchType="lazy" 懒加载策略
fetchType="eager" 立即加载策略
-->
<collection property="ordersList" column="id" ofType="Orders"
select="cn.guardwhy.dao.OrderMapper.findByUid" fetchType="lazy">
</collection>
</resultMap>
<!--一对多嵌套查询-->
<select id="findAllWithOrders" resultMap="userMap2">
select * from user
</select>
</mapper>
设置触发延迟加载的方法
sqlMapConfig.xml
-
配置了延迟加载策略后,在你调用当前对象的equals、clone、hashCode、toString方法时也会触发关联对象的查询。
-
可以在配置文件中使用lazyLoadTriggerMethods配置项覆盖掉上面四个方法。
<settings>
<!--所有方法都会延迟加载-->
<setting name="lazyLoadTriggerMethods" value="toString()"/>
</settings>
全局延迟加载
在Mybatis的核心配置文件中可以使用setting标签修改全局的加载策略。
<settings>
<!--开启全局延迟加载功能-->
<setting name="lazyLoadingEnabled" value="true"/
<!--所有方法都会延迟加载-->
<setting name="lazyLoadTriggerMethods" value="toString()"/>
</settings>
注意点
局部的加载策略优先级高于全局的加载策略。