【MyBatis框架点滴】——MyBatis二级缓存

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介:   在上篇文章的那张图上稍作修改,就可以很明了的看出来什么是二级缓存,它和一级缓存的区别是什么:


  在上篇文章的那张图上稍作修改,就可以很明了的看出来什么是二级缓存,它和一级缓存的区别是什么:


22.png


 一级缓存是SqlSession级别的缓存,二级缓存则是Mapper级别的缓存,这里的Mapper可以看做是Mapper配置文件。多个SqlSession可以操作同一个Mapper配置文件,所以二级缓存比一级缓存的范围要大,它是跨SqlSession的,多个SqlSession可以共享二级缓存中的数据。


开启二级缓存


 MyBatis默认不开启二级缓存,需要在两个地方手动开启:


 1、在MyBatis全局配置文件(SqlMapConfig.xml)中添加如下配置:


<configuration>
  <settings>
    <!-- 开启二级缓存 -->
    <setting name="cacheEnabled" value="true"/>
  </settings>
</configuration>


  2、在相应Mapper配置文件下添加<cache/>


<mapper namespace="com.danny.mybatis.generator.mapper.UserMapper" >
  <!-- 开启本Mapper下的二级缓存 -->
  <cache/>
</mapper> 


  因为二级缓存的存储介质多种多样,不一定是内存,所以还需要让相应的pojo对象实现序列化接口Serializable。

  这时就可以使用二级缓存了。


二级缓存应用



  实验一

@Test
  public void testCache2() throws Exception {
    SqlSession sqlSession1 = sqlSessionFactory.openSession();
    SqlSession sqlSession2 = sqlSessionFactory.openSession();
    //创建代理对象
    UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
    UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);
    // 查询id为1的用户
    User user1 = userMapper1.selectByPrimaryKey(6);
    System.out.println(user1.getUsername());
    sqlSession1.close();
    // 查询id为1的用户
    User user2 = userMapper2.selectByPrimaryKey(6);
    System.out.println(user2.getUsername());    
    sqlSession2.close();      
  }


  日志:


23.png


 由日志可以看出,第一次查询的缓存命中率为0,表示至今为止共执行了1次查询,从缓存中查出数据的次数为0;第二次的缓存命中率为05,表示至今为止共执行了2次查询,从缓存中查出数据的次数为1。


 并且不同的SqlSession查询相同的数据,只有第一次查询执行了sql语句,第二次查询直接从二级缓存中读取。(注意,执行第一次查询后,必须关闭sqlSession,才能将sqlSession中的数据写入到二级缓存区域,如果不关闭,则无法写入二级缓存)



 **实验二**:


@Test
public void testCache2() {
  SqlSession sqlSession1 = sqlSessionFactory.openSession();
  SqlSession sqlSession2 = sqlSessionFactory.openSession();
  SqlSession sqlSession3 = sqlSessionFactory.openSession();
  //创建代理对象
  UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
  UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);
  UserMapper userMapper3 = sqlSession3.getMapper(UserMapper.class);
  // 查询id为1的用户
  User user1 = userMapper1.selectByPrimaryKey(6);
  System.out.println(user1.getUsername());
  sqlSession1.close();
  // 更新id为1的用户
  user1.setUsername("DannyHoo");
  userMapper3.updateByPrimaryKey(user1);
  sqlSession3.commit();
  sqlSession3.close();
  // 查询id为1的用户
  User user2 = userMapper2.selectByPrimaryKey(6);
  System.out.println(user2.getUsername());
  sqlSession2.close();
}


  日志:

24.png


  上面日志中看到,第一次查询的缓存命中率为0;由于sqlSession2在第二次查询之前,sqlSession3执行了改变数据库数据的操作,所以会清空该Mapper下二级缓存中的内容,导致第二次查询的缓存命中率也为0。

  两次实验的结果也可以用下面一张图来表示如下:


25.png


扩展



  1、禁用二级缓存

  在Mapper配置文件的<select>标签内添加useCache="false" 属性,可以设置该查询结果不会放到二级缓存中,每次执行该查询都会执行sql语句。


<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" useCache="false">
  select 
    <include refid="Base_Column_List" />
    from user
    where id = #{id,jdbcType=INTEGER}
</select>


 这种情况比较适合对刷新频率较高的数据的查询。



 2、刷新缓存配置

 从上面可以看出,在mapper的同一个namespace中,如果有其它insert、update、delete操作数据后需要刷新缓存,如果不执行刷新缓存会出现脏读。


 设置Mapper中statement的flushCache属性,可以设置缓存是否刷新。默认情况下为true,即执行了增删改之后会刷新二级缓存;为false时则不会刷新。(使用缓存时如果手动修改数据库表中的查询数据会出现脏读哦。)


<update id="updateByPrimaryKeySelective" parameterType="com.danny.mybatis.generator.pojo.User" flushCache="true">
……
</update>


总结:


 一般情况下,每一个Mapper文件都会设置一个namespace,如果两个Mapper文件的namespace一样的话,那么这两个Mapper其实对应同一个二级缓存区域(这两个Mapper执行的sql查询到的数据将存储在同一个二级缓存区域中),由此看来,二级缓存区域是按照Mapper的namespace来分的。


相关实践学习
通过日志服务实现云资源OSS的安全审计
本实验介绍如何通过日志服务实现云资源OSS的安全审计。
相关文章
|
2月前
|
存储 缓存 NoSQL
mybatisplus一二级缓存
MyBatis-Plus 继承并优化了 MyBatis 的一级与二级缓存机制。一级缓存默认开启,作用于 SqlSession,适用于单次会话内的重复查询;二级缓存需手动开启,跨 SqlSession 共享,适合提升多用户并发性能。支持集成 Redis 等外部存储,增强缓存能力。
|
2月前
|
存储 缓存 NoSQL
Spring Cache缓存框架
Spring Cache是Spring体系下的标准化缓存框架,支持多种缓存(如Redis、EhCache、Caffeine),可独立或组合使用。其优势包括平滑迁移、注解与编程两种使用方式,以及高度解耦和灵活管理。通过动态代理实现缓存操作,适用于不同业务场景。
260 0
|
4月前
|
缓存 Java 数据库连接
Mybatis一级缓存详解
Mybatis一级缓存为开发者提供跨数据库操作的一致性保证,有效减轻数据库负担,提高系统性能。在使用过程中,需要结合实际业务场景选择性地启用一级缓存,以充分发挥其优势。同时,开发者需注意其局限性,并做好事务和并发控制,以确保系统的稳定性和数据的一致性。
139 20
|
6月前
|
缓存 Java 数据库连接
Mybatis一级缓存、二级缓存详讲
本文介绍了MyBatis中的查询缓存机制,包括一级缓存和二级缓存。一级缓存基于同一个SqlSession对象,重复查询相同数据时可直接从缓存中获取,减少数据库访问。执行`commit`操作会清空SqlSession缓存。二级缓存作用于同一namespace下的Mapper对象,支持数据共享,需手动开启并实现序列化接口。二级缓存通过将数据存储到硬盘文件中实现持久化,为优化性能,通常在关闭Session时批量写入缓存。文章还说明了缓存的使用场景及注意事项。
195 7
Mybatis一级缓存、二级缓存详讲
|
6月前
|
缓存 NoSQL Java
Redis应用—8.相关的缓存框架
本文介绍了Ehcache和Guava Cache两个缓存框架及其使用方法,以及如何自定义缓存。主要内容包括:Ehcache缓存框架、Guava Cache缓存框架、自定义缓存。总结:Ehcache适合用作本地缓存或与Redis结合使用,Guava Cache则提供了更灵活的缓存管理和更高的并发性能。自定义缓存可以根据具体需求选择不同的数据结构和引用类型来实现特定的缓存策略。
366 16
Redis应用—8.相关的缓存框架
|
10月前
|
缓存 NoSQL Java
什么是缓存?如何在 Spring Boot 中使用缓存框架
什么是缓存?如何在 Spring Boot 中使用缓存框架
579 0
|
6月前
|
SQL 缓存 Java
框架源码私享笔记(02)Mybatis核心框架原理 | 一条SQL透析核心组件功能特性
本文详细解构了MyBatis的工作机制,包括解析配置、创建连接、执行SQL、结果封装和关闭连接等步骤。文章还介绍了MyBatis的五大核心功能特性:支持动态SQL、缓存机制(一级和二级缓存)、插件扩展、延迟加载和SQL注解,帮助读者深入了解其高效灵活的设计理念。
|
8月前
|
SQL Java 数据库连接
对Spring、SpringMVC、MyBatis框架的介绍与解释
Spring 框架提供了全面的基础设施支持,Spring MVC 专注于 Web 层的开发,而 MyBatis 则是一个高效的持久层框架。这三个框架结合使用,可以显著提升 Java 企业级应用的开发效率和质量。通过理解它们的核心特性和使用方法,开发者可以更好地构建和维护复杂的应用程序。
353 29
|
7月前
|
缓存 Java 数据库连接
十、MyBatis的缓存
十、MyBatis的缓存
126 6
|
6月前
|
Oracle 关系型数据库 Java