mybatis_延迟加载

延迟加载

所谓的 mybatis 延迟加载,指的是当进行多个表之间的关联查询时,先从单表中进行查询,按照一定的设计规则,需要时再对该表所关联的表单继续进行查询

好比如在某个购物网站上填写收货地址时,先加载省份,等用户选择了所在省份后,系统在关联加载处该省份下的城市

延迟加载最主要的一个作用就是减小了数据库的压力

三种不同的加载类型:

1:直接加载:当对一个表执行 select 语句时,马上对该表所关联的表执行 select 语句(将该表与该表所关联的表的数据直接查询出来)

2:侵入式延迟:当对一个表执行 select 语句时,不会对该表的关联表执行 select 查询,但当访问主加载对象的详情属性时,就会马上执行关联的select查询

3:深度延迟:当对一个表执行 select 语句时,不会对该表的关联表执行 select 查询,访问主加载对象的详情也不会对该表的关联对象执行 select 查询,只有当真正访问关联对象详情时,才会执行对关联对象的 select 查询

## 未设置延迟加载时的情况

1:创建mapper

<?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="com.doaoao.dao.TeamDao">

    <!-- 根据teamid 查询team下的篮球队员 -->
    <select id="selectPlayerByTeamId" resultType="Player">
        select id,name from t_player where tid=#{id}
    </select>

    <!-- 关系属性映射关系 -->
    <!-- 集合的数据来自 select 查询,该查询的条件是 selectTeamByIdAlone 查出的id -->
    <resultMap id="teamMapAlone" type="Team">
        <id column="id" property="id"></id>
        <result column="name" property="name"></result>

        <collection property="playerList" ofType="Player" select="selectPlayerByTeamId" column="id"></collection>
    </resultMap>

    <select id="selectTeamByIdAlone" resultMap="teamMapAlone">
        SELECT id,name FROM t_team where id=#{id}
    </select>
</mapper>

2:创建接口

package com.doaoao.dao;
import com.doaoao.bean.Team;
public interface TeamDao {
    Team selectTeamByIdAlone(int id);
}

3:创建测试类

    @Test
    public void selectTeamByIdAlone() {
        Team team = teamDao.selectTeamByIdAlone(2);
        System.out.println(team);
    }

4:执行后的数据分析

// 当未设置延迟加载时,查询主表后会查询该表所关联的表

// 第一条SQL 语句,查询表 t_team
[DEBUG][2019-04-16 15:19:25]==>  Preparing: SELECT id,name FROM t_team where id=? 
[DEBUG][2019-04-16 15:19:25]==> Parameters: 2(Integer)
[TRACE][2019-04-16 15:19:25]<==    Columns: id, name
[TRACE][2019-04-16 15:19:25]<==        Row: 2, huren

// 第二条 SQL 语句,查询表 t_player
[DEBUG][2019-04-16 15:19:25]====>  Preparing: select id,name from t_player where tid=? 
[DEBUG][2019-04-16 15:19:25]====> Parameters: 2(Integer)
[TRACE][2019-04-16 15:19:25]<====    Columns: id, name
[TRACE][2019-04-16 15:19:25]<====        Row: 2, kobe
[DEBUG][2019-04-16 15:19:25]<====      Total: 1
[DEBUG][2019-04-16 15:19:25]<==      Total: 1
Team{id=2, name='huren'}

## 设置延迟加载模式

在配置文件 mybatis.xml中(将下方的内容放在 properties和typeAliases之间)

    <!-- 设置延迟加载 -->
    <settings>
        <!-- 设置延迟加载的总开关 -->
        <setting name="lazyLoadingEnabled" value="true" />

        <!-- 侵入式延迟加载开关 -->
        <!-- 注意:3.4.1把那本之前value默认未true,之后版本默认未false -->
        <setting name="aggressiveLazyLoading" value="true" />
    </settings>

执行后的结果分析

// 只执行了一条 SQL 语句
[DEBUG][2019-04-16 15:47:33]==>  Preparing: SELECT id,name FROM t_team where id=? 
[DEBUG][2019-04-16 15:47:33]==> Parameters: 2(Integer)
[TRACE][2019-04-16 15:47:33]<==    Columns: id, name
[TRACE][2019-04-16 15:47:33]<==        Row: 2, huren
[DEBUG][2019-04-16 15:47:33]<==      Total: 1

 # 当将测试方法修改未如下配置时,会分别执行两条 SQL 语句

@Test
public void selectTeamByIdAlone() {
    Team team = teamDao.selectTeamByIdAlone(1);
    System.out.println(team.getName());
}

 ## 深度延迟加载

将 lazyLoadingEnabled 打开,将 aggressiveLazyLoading 关闭即可。

    <!-- 设置延迟加载 -->
    <settings>
        <!-- 设置延迟加载的总开关 -->
        <setting name="lazyLoadingEnabled" value="true" />

        <!-- 侵入式延迟加载开关 -->
        <!-- 注意:3.4.1把那本之前value默认未true,之后版本默认未false -->
        <setting name="aggressiveLazyLoading" value="true" />
    </settings>

 当执行下方测试方法时,只执行一条SQL语句,因为没有使用到player相关数据

@Test
public void selectTeamByIdAlone() {
    Team team = teamDao.selectTeamByIdAlone(1);
    System.out.println(team.getName());
}

 当执行下方测试方法时,执行两条SQL语句,因为使用到player相关数据

 @Test
public void selectTeamByIdAlone() {
    Team team = teamDao.selectTeamByIdAlone(1);

    // 使用到 player 的数据
    System.out.println(team.getPlayerList().size());
}

... 未完待续

本笔记参考自:小猴子老师教程 http://www.monkey1024.com

转载于:https://www.cnblogs.com/Doaoao/p/10717704.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值