目录
介绍
一级缓存(Local Cache)
一级缓存是 MyBatis 默认提供的缓存机制,也称为“会话缓存”。每个 SqlSession
对象都有自己的一个独立的一级缓存。当在一个 SqlSession
中执行相同的查询语句时,MyBatis 会先查看一级缓存中是否存在之前查询的结果,如果存在则直接从缓存中读取数据,而不会再次发送数据库请求。
特点:
- 作用范围:同一个
SqlSession
内有效。 - 生命周期:随着
SqlSession
的关闭而销毁。 - 自动管理:无需手动配置,MyBatis 自动处理。
- 数据一致性:由于一级缓存的作用范围限制在一个
SqlSession
内,因此可以保证数据的一致性。
MyBatis一级缓存的作用域是同一个SqlSession,在同一个SqlSession中执行两次相同的查询,第一次执行完毕后,Mybatis会将查询到的数据缓存起来(缓存到内存中), 第二次执行相同的查询时,会从缓存中取数据,不再进行数据库的查询,从而提高查询效率。默认情况下,Mybatis开启了一级缓存。但是MyBatis整合Spring Boot时,一级缓存却没有生效。
二级缓存(Global Cache)
二级缓存是跨 SqlSession
的缓存机制,它可以被多个 SqlSession
共享,因此也被称为“全局缓存”或“应用程序级别的缓存”。二级缓存是在 MyBatis 映射文件中通过 <cache>
标签来启用的,它存储在一个特定的命名空间内。
特点:
- 作用范围:整个应用程序范围内有效。
- 生命周期:应用程序运行期间一直存在,除非手动清除。
- 配置方式:需要在映射文件中启用,并且可以在 MyBatis 配置文件中进行一些高级配置。
- 数据一致性:由于二级缓存是跨
SqlSession
的,因此需要特别注意数据的一致性和并发控制问题。通常建议使用缓存插件(如 Ehcache 或 Redis)来管理和控制二级缓存。
一级缓存验证
进行两个相同条件的查询,查看下sql被执行的次数
可以看到此时的sql被执行了两次,并且查询的对象结果比对是false,说明此时的一级缓存失效
失效原因:
当同一个线程开启事务时,同一个sql查询多次会走一级缓存,而不开启事务时,每一查询都是不同的sqlsession,即缓存为“失效”状态 。
添加下 @Transactional 注解再查看打印结果
此时可以看到sql只被执行了一次,且两次的查询结果比对是true,说明此时一级缓存已经生效
查询原理:首先是去一级缓存中去查询:有:直接返回 没有:查询数据库,同时将查询出来的结果存到一级缓存中 第二次查询时先查询的缓存,此时缓存里有第一次查询的数据就直接返回了,所以两者对象比对的结果就是true
接下来在两个查询之间进行一个修改操作,再看下打印结果
可以看到在第一次查询和第二次查询之间执行了更新操作后,第二次查询还是会重新查询数据库,两者比对结果也是false.此时说明缓存被刷新了,
当执行插入、更新、删除,会清空SqlSession中的一级缓存。只有查询的操作,一级缓存才不会被清除。
二级缓存验证
二级缓存的原理和一级缓存原理一样,第一次查询,会将数据放入缓存中,然后第二次查询则会直接去缓存中取。但是一级缓存是基于 sqlSession 的,而 二级缓存是基于 mapper文件的namespace的,也就是说多个sqlSession可以共享一个mapper中的二级缓存区域,并且如果两个mapper的namespace相同,即使是两个mapper,那么这两个mapper中执行sql查询到的数据也将存在相同的二级缓存区域中
未开启二级缓存效果
每调用一次接口,都会重新查询一次数据库
添加mybatis-plus二级缓存配置
实体类实现序列化接口
重启重新测试接口:
可以看到开启二级缓存后,调用同一个接口多次只打印了一条sql