延迟加载又叫懒加载,也叫按需加载。也就是说先加载主信息,在需要的时候,再去加载从信息。
.
在mybatis中,resultMap标签的association标签和collection标签具有延迟加载的功能。
需求
查询订单信息,再按需查找关联的用户信息,即延迟查找关联的信息
1、 创建一个statement来查询订单信息
2、 创建一个statement来查询用户信息
订单映射文件
<resultMap type="com.zyj.mybatis.dto.OrdersExt" id="OrderRstMap">
<!-- 订单信息 -->
<id column="id" property="id"/>
<result column="createtime" property="createtime"/>
<!-- 用户信息(一对一) -->
<!-- select:指定关联查询的查询statement(即查询用户的statement的id),然后将查询结果,封装到property属性指定的变量中 -->
<!-- column:通过column指定的列所查询出的结果,作为select指的statement的入参 -->
<!-- 注意:如果select指定的statement,入参需要多个值,需要在column中{col1=prop1,col2=prop2} -->
<association property="user" select="com.zyj.mybatis.mapper.UserMapper.findUserById" column="user_id"></association>
</resultMap>
<!-- 延迟加载 -->
<select id="findOrderByLazyLoding" resultMap="OrderRstMap">
select * from orders
</select>
用户映射文件
<select id="findUserById" parameterType="int" resultType="com.zyj.mybatis.po.User">
select * from user where id = #{id}
</select>
测试代码
@Test
public void testFindOrderByLazyLoding() {
//......
List<OrdersExt> list = mapper.findOrderByLazyLoding();
//......
}
结果
问题:我们会发现在测试代码中并没有使用订单中的user,但mybatis还是直接查询了user
解决办法:在mybatis的全局配置文件中开启延迟加载
<settings>
<!-- 开启延迟加载,默认值为false
延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。
特定关联关系中可通过设置`fetchType`属性来覆盖该项的开关状态。
-->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 设置积极的懒加载,默认是false (true in ≤3.4.1)
当开启时,任何方法的调用都会加载该对象的所有属性。
否则,每个属性会按需加载(参考lazyLoadTriggerMethods).
-->
<setting name="aggressiveLazyLoading" value="true"/>
</settings>
配置完成后,再执行测试代码,结果只查询了orders
修改测试代码
@Test
public void testFindOrderByLazyLoding() {
//......
List<OrdersExt> list = mapper.findOrderByLazyLoding();
for (OrdersExt ordersExt : list) {
System.out.println(ordersExt.getUser().getId());
}
//......
}
运行结果
结论:这说明延迟加载起作用,而且是按需加载