• MyBatis 延迟加载(十四)


    什么是延迟加载

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

    延迟加载的目的

    减轻数据库服务器的压力,因为我们延迟加载只有在用到需要的数据才会执行查询操作。

    启用延迟加载机制

    Mybatis配置文件中通过两个属性 lazyLoadingEnabledaggressiveLazyLoading 来控制延迟加载和按需加载。

    • lazyLoadingEnabled:是否启用延迟加载,mybatis默认为false,不启用延迟加载。lazyLoadingEnabled属性控制全局是否使用延迟加载,特殊关联关系也可以通过嵌套查询中 fetchType 属性单独配置(fetchType属性值lazy或者eager)。

    • aggressiveLazyLoading:是否按需加载属性,默认值false。该属性为 true 时只要加载对象,就会加载该对象的所有属性;该属性为 false 则会按需加载,即使用到某关联属性时,实时执行嵌套查询加载该属性。

    配置如下:

    <settings>
        <!-- 启用延迟加载特性,不配置默认关闭该特性-->
        <setting name="lazyLoadingEnabled" value="true"></setting>
        <!-- 按需加载: false:使用关联属性,及时加载    true:加载对象,则加载所有属性 -->
        <setting name="aggressiveLazyLoading" value="false"/>
    </settings>
    

    测试延迟加载机制

    • 未开启延迟加载机制

    在 mybastis-config.xml 中关闭延迟加载机制,如下:

    <settings>
      <setting name="lazyLoadingEnabled" value="false" />
    	<setting name="aggressiveLazyLoading" value="false"/>
      ... 
    </settings>
    

    在 MyBatisTest.java 中添加测试代码如下:

    		@Test
        public void lazyLoadingTest() {
            RoleEntity roleEntity = gameMapper.selectRoleById(1);
            //System.out.println(roleEntity.getMoney());
        }
    

    执行测试,结果如下:

    2020-08-11 10:22:57,766 [main] [mapper.GameMapper.selectRoleById]-[DEBUG] ==>  Preparing: select * from tb_role where id=? 
    2020-08-11 10:22:57,810 [main] [mapper.GameMapper.selectRoleById]-[DEBUG] ==> Parameters: 1(Integer)
    2020-08-11 10:22:57,857 [main] [mapper.GameMapper.selectAccountById]-[DEBUG] ====>  Preparing: select * from tb_account where id=? 
    2020-08-11 10:22:57,857 [main] [mapper.GameMapper.selectAccountById]-[DEBUG] ====> Parameters: 1(Integer)
    2020-08-11 10:22:57,857 [main] [mapper.GameMapper.selectAccountById]-[DEBUG] <====      Total: 1
    2020-08-11 10:22:57,857 [main] [mapper.GameMapper.selectRoleById]-[DEBUG] <==      Total: 1
    

    从以上结果可以看出,打印了两条 SQL 语句,说明执行了关联查询。

    • 开启延迟加载机制
      <settings>
          <!-- 启用延迟加载特性,不配置默认关闭该特性-->
          <setting name="lazyLoadingEnabled" value="true"></setting>
          <!-- 按需加载: false:使用关联属性,及时加载    true:加载对象,则加载所有属性 -->
          <setting name="aggressiveLazyLoading" value="false"/>
      </settings>
      

      再次执行测试代码,结果如下:

      2020-08-11 10:26:31,779 [main] [mapper.GameMapper.selectRoleById]-[DEBUG] ==>  Preparing: select * from tb_role where id=? 
      2020-08-11 10:26:31,810 [main] [mapper.GameMapper.selectRoleById]-[DEBUG] ==> Parameters: 1(Integer)
      2020-08-11 10:26:31,982 [main] [mapper.GameMapper.selectRoleById]-[DEBUG] <==      Total: 1
      

      启动延迟加载后,只打印了一条 SQL 语句。

      现在我把测试代码修改一下,如下:

      		@Test
          public void lazyLoadingTest() {
              RoleEntity roleEntity = gameMapper.selectRoleById(1);
              System.out.println(roleEntity.getMoney());
          }
      

      将查询的主表的 money 属性值打印出来,执行测试结果如下:

      2020-08-11 10:27:47,982 [main] [mapper.GameMapper.selectRoleById]-[DEBUG] ==>  Preparing: select * from tb_role where id=? 
      2020-08-11 10:27:48,029 [main] [mapper.GameMapper.selectRoleById]-[DEBUG] ==> Parameters: 1(Integer)
      2020-08-11 10:27:48,185 [main] [mapper.GameMapper.selectRoleById]-[DEBUG] <==      Total: 1
      2000
      

      看到了吧,还是只有一条 SQL 查询语句,说明并未执行关联查询。

      现在我又把配置修改一下,

      <setting name="aggressiveLazyLoading" value="true"/>
      

      然后执行如下测试代码

      		@Test
          public void lazyLoadingTest() {
              RoleEntity roleEntity = gameMapper.selectRoleById(1);
              //System.out.println(roleEntity.getMoney());
          }
      

      测试结果如下:

      2020-08-11 10:41:00,826 [main] [mapper.GameMapper.selectRoleById]-[DEBUG] ==>  Preparing: select * from tb_role where id=? 
      2020-08-11 10:41:00,888 [main] [mapper.GameMapper.selectRoleById]-[DEBUG] ==> Parameters: 1(Integer)
      2020-08-11 10:41:01,029 [main] [mapper.GameMapper.selectRoleById]-[DEBUG] <==      Total: 1
      

      现在还是只打印了一条 SQL 查询语句,说明并未执行关联查询。

      修改一下测试代码如下:

      		@Test
          public void lazyLoadingTest() {
              RoleEntity roleEntity = gameMapper.selectRoleById(1);
              System.out.println(roleEntity.getMoney());
          }
      

      再次执行测试结果如下:

      2020-08-11 10:43:51,544 [main] [mapper.GameMapper.selectRoleById]-[DEBUG] ==>  Preparing: select * from tb_role where id=? 
      2020-08-11 10:43:51,576 [main] [mapper.GameMapper.selectRoleById]-[DEBUG] ==> Parameters: 1(Integer)
      2020-08-11 10:43:51,748 [main] [mapper.GameMapper.selectRoleById]-[DEBUG] <==      Total: 1
      2020-08-11 10:43:51,748 [main] [mapper.GameMapper.selectAccountById]-[DEBUG] ==>  Preparing: select * from tb_account where id=? 
      2020-08-11 10:43:51,748 [main] [mapper.GameMapper.selectAccountById]-[DEBUG] ==> Parameters: 1(Integer)
      2020-08-11 10:43:51,763 [main] [mapper.GameMapper.selectAccountById]-[DEBUG] <==      Total: 1
      2000
      

      现在打印了两条 SQL 查询语句,说明已经执行了关联查询。

    总结

    • 什么是延迟加载
    • 延迟加载的目的是什么
    • 如何开启延迟加载
    • 按需加载和完全加载在区别是什么
    作者:Binge
    本文版权归作者和博客园共有,转载必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
  • 相关阅读:
    iphone4 wifi超时设置修改
    siteminder sso agent 初探
    [读书]35前要掌握的66种基本能力序
    Secrets of Successful Project Management
    成功项目管理的秘密
    一位乞丐给我上的MBA课程
    [读书]35前要掌握的66种基本能力第2节
    简单,有规律
    网盘使用手记
    更好地领导一个项目的诀窍
  • 原文地址:https://www.cnblogs.com/binbingg/p/13802752.html
Copyright © 2020-2023  润新知