Mybatis查询时的延迟加载解析

 更新时间:2023年10月27日 11:10:58   作者:Forrit  
这篇文章主要介绍了Mybatis查询时的延迟加载解析,先从单表查询,需要时再从关联表去关联查询,能大大提高数据库性能,因为查询单表要比关联查询多张表速度要快,延迟加载分为两种:深度延时加载,侵入式延迟加载,需要的朋友可以参考下

Mybatis延迟加载

什么是延迟加载呢?

通俗的讲就是按需加载,我们需要什么的时候再去进行什么操作。

什么时候会用到延迟加载呢?

多表单独查询的时候。

而且先从单表查询,需要时再从关联表去关联查询,能大大提高数据库性能,因为查询单表要比关联查询多张表速度要快。 延迟加载分为两种:深度延时加载,侵入式延迟加载

如何开启延时加载?

两种方法:

1.在collection标签中:

  <select id="selectByMinorId"  resultMap="selectMinorMap">
        select cid,cname from country where cid =#{id}
  </select>
    
    <resultMap id="selectMinorMap" type="Country">
        <id column="cid" property="cid"/>
        <result column="cname" property="cname"/>
        <collection column="cid" property="mino" ofType="Minor" select="selectByMinorIds" fetchType="lazy"/>
				//使用fetch属性的值为true,默认开启深度延迟加载
    </resultMap>
    
    <select id="selectByMinorIds" resultType="com.example.mytest01.pojo.Minor" >
    	select mname from minor where countryid =#{cid}
	</select>

2.mybatis.xml中进行配置

<settings>

<!--延迟加载总开关,打开后,默认的是深度延时加载 -->
<setting name="lazyLoadingEnabled" value="true" />

<!--侵入式延迟加载开关 -->
<!--3.4.1版本之前默认是true,之后默认是false -->
<setting name="aggressiveLazyLoading" value="true" />

</settings>

加载特点

侵入式延迟: 执行对主加载对象的查询时,不会执行对关联对象的查询。但当要访问主加载对象的详情属性时,就会马上执行关联对象的select查询。

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

MyBatis 的延迟加载只是对关联对象的查询有迟延设置,对于主加载对象都是直接执行查询语句的。

举例: mapper.xml:

<?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">
<!-- namespace:填写映射当前的Mapper接口,所有的增删改查的参数和返回值类型,
		就可以直接填写缩写,不区分大小写,直接通过方法名去找类型-->
<mapper namespace="com.example.mytest01.dao.IMinorDao">


    <select id="selectByMinorId"  resultMap="selectMinorMap">
        select cid,cname from country where cid =#{id}
    </select>
    <resultMap id="selectMinorMap" type="Country">
        <id column="cid" property="cid"/>
        <result column="cname" property="cname"/>
        <collection column="cid" property="mino" ofType="Minor" select="selectByMinorIds"/>

    </resultMap>
    <select id="selectByMinorIds" resultType="com.example.mytest01.pojo.Minor" >
    select mname from minor where countryid =#{cid}
</select>
</mapper>

当不开启延迟加载时:

@Autowired
private IMinorDao m;
 @Test
    void hah(){
      Country c =m.selectByMinorId(1);
      //System.out.println(c.getCname());
  }

在这里插入图片描述

进行两次查询;

@Autowired
private IMinorDao m;
 @Test
    void hah(){
      //Country c =m.selectByMinorId(1);
      System.out.println(c.getCname());
  }

在这里插入图片描述

进行两次查询;

重点来了: 当开深度启延迟加载时:

@Autowired
private IMinorDao m;
 @Test
    void hah(){
      Country c =m.selectByMinorId(1);
      //System.out.println(c.getCname());
  }

在这里插入图片描述

通过日志观察到,只查询一次,还未进行第二次查询;

@Autowired
private IMinorDao m;
 @Test
    void hah(){
      //Country c =m.selectByMinorId(1);
      System.out.println(c.getCname());
  }

在这里插入图片描述

当查询主加载对象的详情属性时,依旧只进行了第一次的查询; .

@Autowired
private IMinorDao m;
 @Test
    void hah(){
      //Country c =m.selectByMinorId(1);
      //System.out.println(c.getCname());
      System.out.println(c.getMino());
  }

在这里插入图片描述

看到这里我们会发现:只有当查询主加载对象的关联属性时,才进行了两次查询

当开启侵入式延迟加载时:

@Autowired
private IMinorDao m;
 @Test
    void hah(){
      Country c =m.selectByMinorId(1);
      //System.out.println(c.getCname());
  }

在这里插入图片描述

通过日志观察到,只查询一次,还未进行第二次查询;

@Autowired
private IMinorDao m;
 @Test
    void hah(){
      //Country c =m.selectByMinorId(1);
      System.out.println(c.getCname());
  }

在这里插入图片描述

与深度延迟加载不同的时:当查询主属性的详细信息时,Mybatis就已经进行了第二次的关联属性的查询;

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

相关文章

  • Java枚举的使用与反射应用方式

    Java枚举的使用与反射应用方式

    枚举类型是一种特殊的类,限定为固定实例集合,且是类型安全和线程安全的,枚举类型不可继承,但可以添加属性和方法,支持单例模式,枚举常量可以通过反射获取和操作,提供了灵活性和扩展性
    2024-09-09
  • MyBatis-Plus自定义SQL的详细过程记录

    MyBatis-Plus自定义SQL的详细过程记录

    Java开发使用mybatis-plus来执行sql操作,往往比mybatis能够省时省力,下面这篇文章主要给大家介绍了关于MyBatis-Plus自定义SQL的相关资料,需要的朋友可以参考下
    2022-02-02
  • Java实战之晚会抽奖系统的实现

    Java实战之晚会抽奖系统的实现

    这篇文章主要介绍了如何利用Java语言编写一个晚会抽奖系统,文中采用到的技术有Jdbc、Servlert、JavaScript、JQuery、Ajax等,感兴趣的可以学习一下
    2022-03-03
  • 基于java编写局域网多人聊天室

    基于java编写局域网多人聊天室

    这篇文章主要为大家详细介绍了基于java编写局域网多人聊天室的相关资料,使用socket基于java编写一个局域网聊天室,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-09-09
  • 详细解读Java的串口编程

    详细解读Java的串口编程

    这篇文章主要介绍了详细解读Java的串口编程,而文中讲解的示例主要针对于JavaComm和RxTx这两个库,需要的朋友可以参考下
    2015-08-08
  • Java基础知识之CharArrayReader流的使用

    Java基础知识之CharArrayReader流的使用

    这篇文章主要介绍了Java基础知识之CharArrayReader流的使用,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • SpringBoot使用AOP,内部方法失效的解决方案

    SpringBoot使用AOP,内部方法失效的解决方案

    这篇文章主要介绍了SpringBoot使用AOP,内部方法失效的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • SpringCloud微服务架构升级汇总

    SpringCloud微服务架构升级汇总

    这篇文章主要介绍了SpringCloud微服务架构升级汇总,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值,需要的朋友可以参考下
    2019-06-06
  • java 中堆内存和栈内存理解

    java 中堆内存和栈内存理解

    这篇文章主要介绍了java 中的堆内存和栈内存的知识,有需要的朋友可以参考下
    2017-03-03
  • 使用AOP的@Around后无返回值的解决

    使用AOP的@Around后无返回值的解决

    这篇文章主要介绍了使用AOP的@Around后无返回值的解决,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02

最新评论