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延迟加载内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 在idea中git实现里查看历史代码方式

    在idea中git实现里查看历史代码方式

    这篇文章主要介绍了在idea中git里查看历史代码的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-10-10
  • Java中this的用法实例总结

    Java中this的用法实例总结

    JAVA中的this是一个非常重要的模块,在编程中有非常重要的地位,擅长用this的人常常可以使程序更加简洁和方便,下面这篇文章主要给大家介绍了关于Java中this用法的相关资料,需要的朋友可以参考下
    2022-08-08
  • Java 语言实现清除带 html 标签的内容方法

    Java 语言实现清除带 html 标签的内容方法

    下面小编就为大家带来一篇Java 语言实现清除带 html 标签的内容方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-02-02
  • HttpsURLConnection上传文件流(实例讲解)

    HttpsURLConnection上传文件流(实例讲解)

    下面小编就为大家带来一篇HttpsURLConnection上传文件流(实例讲解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • Spring核心容器之Bean创建过程详解

    Spring核心容器之Bean创建过程详解

    这篇文章主要介绍了Spring核心容器之Bean创建过程详解,获取 Bean 的方法是 getBean,其来自 BeanFactory 继承的AbstractAutowireCapableBeanFactory 抽象类继承的AbstractBeanFactory 抽象类中,需要的朋友可以参考下
    2023-11-11
  • 关于spring属性占位符用法

    关于spring属性占位符用法

    这篇文章主要介绍了关于spring属性占位符用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • Java中logback 自动刷新不生效的问题解决

    Java中logback 自动刷新不生效的问题解决

    本文主要介绍了Java中logback 自动刷新不生效的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-05-05
  • Java自定义Enum的实现示例

    Java自定义Enum的实现示例

    Java中的自定义Enum类型是一种特殊的类,用于表示固定数量的常量值,本文主要介绍了Java自定义Enum的实现示例,具有一定的参考价值,感兴趣的可以了解一下
    2023-12-12
  • java代理模式与动态代理模式详解

    java代理模式与动态代理模式详解

    代理就是一个人或者一个机构代表另一个人或者另一个机构采取行动。在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之前起到中介的作用
    2014-02-02
  • Spring Boot 集成Shiro的多realm配置过程

    Spring Boot 集成Shiro的多realm配置过程

    这篇文章主要介绍了Spring Boot 集成Shiro的多realm配置,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-10-10

最新评论