mybatis 延迟加载的深入理解

 更新时间:2019年01月15日 14:53:55   作者:一号线  
这篇文章主要介绍了mybatis 延迟加载的深入理解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

什么是延迟加载

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

什么时候会执行延迟加载

配置之后在对关联对象进行查询时使用延迟加载。

延迟加载策略

直接加载

遇到代码中查询语句,马上到DB中执行select语句进行查询。(这种只能用于多表单独查询)

侵入式延迟加载

将关联对象的详情(具体数据,如id、name)侵入到主加载对象,作为主加载对象的详情的一部分出现。当要访问主加载对象的详情时才会查询主表,但由于关联对象详情作为主加载对象的详情一部分出现,所以这个查询不仅会查询主表,还会查询关联表。

深度延迟加载

将关联对象的详情(具体数据,如id、name)侵入到主加载对象,作为主加载对象的详情的一部分出现。当要访问主加载对象的详情时才会查询主表,但由于关联对象详情作为主加载对象的详情一部分出现,所以这个查询不仅会查询主表,还会查询关联表。

使用延迟加载的目的

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

如何开启延迟加载功能

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

需要在SqlMapConfig.xml文件中通过setting标签配置来开启延迟加载功能

开启延迟加载的属性:

  • lazyLoadingEnabled:全局性设置懒加载。如果设为‘false',则所有相关联的都会被初始化加载。默认为false
  • aggressiveLazyLoading:当设置为‘true'的时候,懒加载的对象可能被任何懒属性全部加载。否则,每个属性都按需加载。默认为true

配置

  <settings>
    <setting name ="aggressiveLazyLoading" value="false"/>
    <!--开启延迟加载-->
    <setting name="lazyLoadingEnabled" value="true"/>
  </settings>

我们用关联查询来实现延迟加载,假设我们现在要查出用户和用户角色。

首先我们在user中添加查询userVo的方法和xml。

<!--userMapper.xml-->

....
<resultMap id="BaseResultMap" type="com.redstar.basemapper.pojo.User">
    <id column="id" jdbcType="VARCHAR" property="id"/>
    <result column="name" jdbcType="VARCHAR" property="name"/>
    <result column="age" jdbcType="INTEGER" property="age"/>
    <result column="role_id" jdbcType="INTEGER" property="roleId"/>
  </resultMap>
  <resultMap id="userRoleMapSelect" type="com.redstar.basemapper.pojo.UserVo">
    <association property="user" resultMap="BaseResultMap"/>
    <association property="role" fetchType="lazy" column="{id=role_id}"
           select="com.redstar.basemapper.dao.RoleMapper.getRoleById"/>
  </resultMap>
  <sql id="Base_Column_List">
  id, `name`, age, role_id
 </sql>
  <select id="getUserVo" resultMap="userRoleMapSelect">
   select * from user where id=#{userId}
  </select>
...
  
  
  
  <!--roleMapper.xml-->
...  
  <resultMap id="BaseResultMap" type="com.redstar.basemapper.pojo.Role">
  <id column="id" jdbcType="INTEGER" property="id" />
  <result column="role_name" jdbcType="VARCHAR" property="roleName" />
 </resultMap>
 <sql id="Base_Column_List">
  id, role_name
 </sql>
 <select id="getRoleById" resultMap="BaseResultMap">
  select * from role where id=#{id}
 </select>
... 

测试用例

@RunWith(SpringRunner.class)
@SpringBootTest
public class BaseMapperApplicationTests {
  @Autowired
  private UserMapper userMapper;

  @Autowired
  private RoleMapper roleMapper;

  @Test
  public void getUserVo() {
    System.out.println(userMapper.getUserVo("12312232"));
//    System.out.println(userMapper.getUserById("12312232"));
//    System.out.println(roleMapper.getRoleById(1));

  }
}

输出结果:

UserVo{user=User [Hash = 1937575946, id=12312232, name=哇哈哈啊娃哈哈哇哈哈哈哈哈哈哈, age=48, roleId=1, serialVersionUID=1], role=Role [Hash = 317053574, id=1, roleName=admin, serialVersionUID=1]}

注意

许多对延迟加载原理不太熟悉的朋友会经常遇到一些莫名其妙的问题:有些时候延迟加载可以得到数据,有些时候延迟加载就会报错,为什么会出现这种情况呢?

MyBatis 延迟加载是通过动态代理实现的,当调用配直为延迟加载的属性方法时, 动态代理的操作会被触发,这些额外的操作就是通过 MyBatis 的 SqlSessio口去执行嵌套 SQL 的 。由于在和某些框架集成时, SqlSession 的生命周期交给了框架来管理,因此当对象超出SqlSession 生命周期调用时,会由于链接关闭等问题而抛出异常 。 在和 Spring 集成时,要确保只能在 Service 层调用延迟加载的属性 。 当结果从 Service 层返回至 Controller 层时, 如果获取延迟加载的属性值,会因为 SqlSessio口已经关闭而抛出异常 。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • SpringBoot打成jar包瘦身方法总结

    SpringBoot打成jar包瘦身方法总结

    springBoot打包的时候代码和jar包打包在同一个jar包里面,会导致jar包非常庞大,下面这篇文章主要给大家介绍了关于SpringBoot打的jar包瘦身方法的相关资料,需要的朋友可以参考下
    2022-12-12
  • Dubbo服务校验参数的解决方案

    Dubbo服务校验参数的解决方案

    这篇文章主要介绍了Dubbo服务如何优雅的校验参数,Dubbo框架本身是支持参数校验的,同时也是基于JSR303去实现的,今天通过示例代码介绍下详细实现过程,需要的朋友可以参考下
    2022-03-03
  • 详解Spring boot/Spring 统一错误处理方案的使用

    详解Spring boot/Spring 统一错误处理方案的使用

    这篇文章主要介绍了详解Spring boot/Spring 统一错误处理方案的使用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-06-06
  • Linux系统下搭建Java开发环境

    Linux系统下搭建Java开发环境

    本文主要是记录了如何在Linux环境下一步步安装JAVA JDK环境,非常简单实用,有需要的朋友可以参考下
    2014-10-10
  • Spring依赖注入中的@Resource与@Autowired详解

    Spring依赖注入中的@Resource与@Autowired详解

    这篇文章主要介绍了Spring依赖注入中的@Resource与@Autowired详解,提到Spring依赖注入,大家最先想到应该是@Resource和@Autowired,对于Spring为什么要支持两个这么类似的注解却未提到,属于知其然而不知其所以然,本文就来做详细讲解,需要的朋友可以参考下
    2023-09-09
  • JVM常见垃圾收集器学习指南

    JVM常见垃圾收集器学习指南

    这篇文章主要为大家介绍了JVM常见垃圾收集器学习指南,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • java实现登录验证码

    java实现登录验证码

    这篇文章主要为大家详细介绍了java实现登录验证码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-06-06
  • Java和C#输入输出流的方法(详解)

    Java和C#输入输出流的方法(详解)

    下面小编就为大家带来一篇Java和C#输入输出流的方法(详解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-10-10
  • Spring整合MyBatis图示过程解析

    Spring整合MyBatis图示过程解析

    这篇文章主要介绍了Spring整合MyBatis图示过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • java如何根据IP获取当前区域天气信息详解

    java如何根据IP获取当前区域天气信息详解

    根据IP自动获取当地的天气预报信息这个功能大家应该都遇到过,天气预报信息用途非常广泛,篇文章主要给大家介绍了关于java如何根据IP获取当前区域天气信息的相关资料,需要的朋友可以参考下
    2021-08-08

最新评论