zoukankan      html  css  js  c++  java
  • MyBatis中的延迟加载策略

    一:延迟加载

    1.了解延迟加载:

    延迟加载又叫懒加载,也叫按需加载,也就是说先加载主信息,需要的时候,再去加载从信息。代码中有查询语句,当执行到查询语句时,并不是马上去DB中查询,而是根据设置的延迟策略将查询向后推迟。

    2.延迟加载的好处:

    先从单表查询、需要时再从关联表去关联查询,大大提高数据库性能,减轻数据库服务器的压力,因为查询单表要比关联查询多张表速度要快。

    3.如何开启MyBatis的延迟加载:

    Mybatis的延迟加载功能默认是关闭的

    需要在mybatis-config.xml(mybatis的核心配置)文件中通过setting标签配置来开启延迟加载功能

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

    4.延迟加载的resultMap

    4.1当在resultMao中使用过association或者collection进行关系映射之后才能使用MyBatis的延迟加载策略

    4.2 延迟加载需要两个select语句来完成

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

    5.关联对象的加载时机

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

    1.直接加载

    即执行对象的select语句,完成对主加载马上执行对关联对象的select查询。

    2.侵入式延迟加载(aggressiveLazyLoading) 也可看做立即加载

    执行对主加载对象的查询时,不会执行对关联对象的查询。但是当要访问主加载对象的详情时马上执行对关联对象的select查询。即对关联对象的执行查询,侵入到了主加载对象的访问详情中。也可理解为:将关联对象的详情侵入到主加载对象的详情中去,即将关联对象的详情作为主加载对象的一部分出现了!

    3.深度延迟加载

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

    六:延迟加载测试案例

    1.将俩张表的关联关系在实体类中体现出来,也就是在一张表中添加另一张表的对象

    2.创建Dao层的方法一级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">
    <mapper namespace="com.yjc.dao.ISmbmsDao">
        <resultMap id="SmbmsProviderResult" type="SmbmsBill">
            <collection property="smbmsProvider" ofType="SmbmsProvider" select="getSmbmsProvider" column="providerId">
            </collection>
    
        </resultMap>
        <select id="getSmbmsBillList" resultMap="SmbmsProviderResult">
            select * from  smbms.smbms_bill where id=#{id}
        </select>
        <select id="getSmbmsProvider" resultType="SmbmsProvider">
            select * from  smbms.smbms_provider where  id=#{providerId}
        </select>
    
    </mapper>

    3.测试类

    public class YiTest {
        public static void main(String[] args) {
            SqlSession session = SqlSessionUtils.getSession();
            ISmbmsDao mapper = session.getMapper(ISmbmsDao.class);
            SmbmsBill smbmsBillList = mapper.getSmbmsBillList(1);
    }
    }

    当没有开启延迟加载策略的时候,MyBatis默认是直接加载当执行上面的测试类的时候结果如下

    1.直接加载

     如上图所示,一共向数据库发送了两条请求,此时我们开启侵入式延迟加载 然后再执行上面的测试

    2.侵入式延迟加载

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

    此时测试的结果如下

     由于我们只进行了查询操作,并没有对查询出来的主对象进行操作(访问改对象的属性或及方法)所以此时并没有进行加载关联的查询

    那么我们接下来访问一些主对象的一些属性

    结果如下

    这就是侵入式延迟加载的效果,当对主加载对象进行操作的时候就会去加载关联对象(向数据库发送请求)

    3.深度式延迟加载

    在核心配置文件中修改setting节点

              <!--开启延迟加载-->
            <setting name="lazyLoadingEnabled" value="true"/>
            <!--value为true时为侵入式延迟加载,false为深入式延迟加载-->
            <setting name="aggressiveLazyLoading" value="false"/>    

    修改完成之后继续执行上次执行的测试方法

     从上面的结果中可以看到同样的测试方法,开始深度式延迟之后只向数据库发送了一次请求,这是因为我们在测试类中只访问了主对象的属性,并没有使用关联对象的任何属性

    那么接下来我们修改测试类,在测试类中添加对关联对象的访问

    public class YiTest {
        public static void main(String[] args) {
            SqlSession session = SqlSessionUtils.getSession();
            ISmbmsDao mapper = session.getMapper(ISmbmsDao.class);
            SmbmsBill smbmsBillList = mapper.getSmbmsBillList(1);
            //获取关联对象中的proName属性
            System.out.println(smbmsBillList.getSmbmsProvider().getProName());
    
        }
    }

    测试结果如下

     当我们访问关联对象时候就发送请求进行对关联关系的加载,这就是MyBatis中的深度式延迟加载策略

    以上就是我对MyBatis的延迟加载机制的理解,有不足之处还请指出

  • 相关阅读:
    I Hate It HDU
    线段树为什么要开4倍空间
    敌兵布阵 HDU
    线段树 模板
    线段树原理详解
    HDU5037 Frog
    HDU5187 zhx's contest
    HDU5307 He is Flying
    UOJ#34. 多项式乘法
    Bzoj4766 文艺计算姬
  • 原文地址:https://www.cnblogs.com/yjc1605961523/p/11671803.html
Copyright © 2011-2022 走看看