Mybatis六----延迟加载

 

 

 

一. 延迟加载

  Mybatis中延迟加载又称为懒加载,是指在进行关联查询时,按照设置延迟规则推迟对关联对象的select查询,延迟加载可以有效的减少数据库的压力。延迟加载仅仅是对关联对象的查询有延迟设置,对于主加载对象都是直接执行查询。

  Mybatis根据关联对象查询的select语句的执行时机,分为以下三种:直接加载,侵入式延迟加载,深度延迟加载。

  PS:延迟加载的应用要求,关联对象的查询与主加载对象的查询必须是分别进行的select语句,不能是使用多表连接所进行的select查询。因为多表连接查询,本质上是对一个表的查询,对由多个表连接后形成的一张表的查询,会一次性将多个表的所有信息查询出来。

二. 直接加载

  执行完主加载对象的查询后,马上执行关联对象的select查询。 

  1)在mybatis主配置文件中,设置全局属性lazyLoadingEnabled的值为false,那么对于关联对象的查询,都将采用直接加载。即在主加载对象查询后,立即查询关联对象。 

    <settings>
        <!-- 关闭延迟加载 -->
         <setting name="lazyLoadingEnabled" value="false"/>
    </settings>

  2)实体类:

public class HeadTeacher {

    private Integer id;
    private String name;
    // private Clazz clazz;                //这边不引用,防止关联查询导致死循环
    
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "HeadTeacher [id=" + id + ", name=" + name + "]";
    }

}


public class Clazz {

    private Integer id;
    private String className;
    private Set<HeadTeacher> headTeacher = new LinkedHashSet<>();

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getClassName() {
        return className;
    }

    public void setClassName(String className) {
        this.className = className;
    }

    public Set<HeadTeacher> getHeadTeacher() {
        return headTeacher;
    }

    public void setHeadTeacher(Set<HeadTeacher> headTeacher) {
        this.headTeacher = headTeacher;
    }

    @Override
    public String toString() {
        return "Clazz [id=" + id + ", className=" + className + ", headTeacher=" + headTeacher + "]";
    }

}

  3)映射文件

<mapper namespace="com.mybatisdemo.dao.ClazzDao">

    <resultMap type="com.mybatisdemo.beans.Clazz" id="clazzMapper">
        <id column="id" property="id"/>
        <result column="class_name" property="className"/>
        <collection property="headTeacher" ofType="com.mybatisdemo.beans.HeadTeacher" 
                column="head_teacher_id" select="com.mybatisdemo.dao.HeaderTeacherDao.queryHeadTeacherById"/>
    </resultMap>
    
    <select id="queryClazzById" parameterType="int" resultMap="clazzMapper">
        select id,class_name,head_teacher_id from clazz where id = #{id}
    </select>
    
</mapper>


<mapper namespace="com.mybatisdemo.dao.HeaderTeacherDao">

    <resultMap type="com.mybatisdemo.beans.HeadTeacher" id="headTeacherMapper">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
    </resultMap>
    
    <select id="queryHeadTeacherById" parameterType="int" resultMap="headTeacherMapper">
        select id,name from head_teacher where id = #{id}
    </select>
    
</mapper>

  4)测试类:

    @Test
        public void testClazz() {
        ClazzDao clazzDao = sqlSession.getMapper(ClazzDao.class);
        Clazz clazz = clazzDao.queryClazzById(1);
        System.out.println(clazz.getClassName());                //1
        System.out.println(clazz.getHeadTeacher().size());        //2
    }

我们在1处打断点跟踪,控制台打印如下:

发现我们在进行主加载对象查询时,也对关联对象进行了查询。这就是直接加载。

三. 深度延迟加载

  执行对主加载对象的查询时,不会执行对关联对象的查询,访问主加载对象的详情也不会执行对关联对象的查询。只有真正访问关联对象的详情时,才会执行对关联对象的查询。

  1)mybatis主配置文件

    <settings>
        <!-- 开启延迟加载 -->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!-- 侵入式延迟加载关闭 -->
        <setting name="aggressiveLazyLoading" value="false"/>
    </settings>

  我们在1处打断点,控制台打印如下:

执行一步到2处,控制台打印如下:

再执行一步,控制台打印:

即:深度延迟加载就是在查询关联对象的详情时,才会执行对关联对象的查询。

三. 侵入式延迟加载

  侵入式延迟加载,就是执行对主加载对象的查询时,不会执行对关联对象的查询。但当要访问主加载对象的详情时,就会马上执行关联对象的查询。即对关联对象的查询,侵入到了主加载对象详情查询中。

  1)mybatis主配置文件

    <settings>
        <!-- 开启延迟加载 -->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!-- 侵入式延迟加载关闭 -->
        <setting name="aggressiveLazyLoading" value="true"/>
    </settings>

在1处断点,控制台打印如下

执行一步到断点2处,控制台打印如下

发现在查询主加载对象的详情时,已经侵入进行了关联对象的查询。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值