Mybatis中的延迟加载详细解读

 更新时间:2023年10月27日 10:12:16   作者:夜聆离殇  
这篇文章主要介绍了Mybatis中的延迟加载详细解读,Mybatis中延迟加载又称为懒加载,是指在进行关联查询时,按照设置延迟规则推迟对关联对象的select查询,延迟加载可以有效的减少数据库的压力,需要的朋友可以参考下

一. 延迟加载

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处,控制台打印如下

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

到此这篇关于Mybatis中的延迟加载详细解读的文章就介绍到这了,更多相关Mybatis延迟加载内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot常用注解详细整理

    SpringBoot常用注解详细整理

    大家好,本篇文章主要讲的是SpringBoot常用注解详细整理,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2021-12-12
  • Java利用JSch实现SSH远程操作的技术指南

    Java利用JSch实现SSH远程操作的技术指南

    在日常开发中,许多应用需要通过 SSH 协议远程连接服务器来执行命令、上传或下载文件,JSch是一个功能强大的 Java 库,它提供了便捷的接口来实现 SSH 连接和其他远程管理功能,本文将介绍 JSch 的基本功能,并通过实际代码示例帮助您快速上手,需要的朋友可以参考下
    2025-03-03
  • Spring在多线程下@Resource注入为null的问题

    Spring在多线程下@Resource注入为null的问题

    这篇文章主要介绍了Spring在多线程下@Resource注入为null的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-02-02
  • Java设计模式之中介者模式

    Java设计模式之中介者模式

    这篇文章介绍了Java设计模式之中介者模式,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-10-10
  • 使用Java校验SQL语句的合法性五种解决方案

    使用Java校验SQL语句的合法性五种解决方案

    这篇文章主要介绍了如何用java校验SQL语句的合法性(提供五种解决方案),使用JDBC API和JSqlParser库、正则表达式、ANTLR解析器生成器或Apache Calcite库都可以实现校验SQL语句的合法性,需要的朋友可以参考下
    2023-04-04
  • Springboot转发重定向实现方式解析

    Springboot转发重定向实现方式解析

    这篇文章主要介绍了springboot转发重定向实现方式解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • JDBC使用Statement修改数据库

    JDBC使用Statement修改数据库

    这篇文章主要为大家详细介绍了JDBC使用Statement修改数据库,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-08-08
  • JVM垃圾回收器选型与调优方式

    JVM垃圾回收器选型与调优方式

    本文介绍了JVM垃圾回收器选型与调优的关键原理和实战技巧,包括基础数据结构、API使用、常见问题及解决方案、性能优化建议等,并提供了实际项目中的最佳实践,通过理解这些知识,可以有效提升代码质量
    2026-05-05
  • java实现区域内屏幕截图示例

    java实现区域内屏幕截图示例

    这篇文章主要介绍了java截图示例,需要的朋友可以参考下
    2014-04-04
  • 详解Spring IOC 容器启动流程分析

    详解Spring IOC 容器启动流程分析

    这篇文章主要介绍了Spring IOC 容器启动流程分析,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-08-08

最新评论