Mybatis一、二级缓存解析

文章目录

一级缓存

一级缓存是SqlSession级别的,通过同一个SqlSession查询的数据会被缓存,下次查询相同的数据,就会从缓存中直接获取,不会从数据库重新访问。(默认开启)

基本特性

  • 默认开启:SqlSession 级别的缓存
  • 作用范围:同一个 SqlSession
  • 生命周期:与 SqlSession 一致
  • 自动失效:执行 INSERT、UPDATE、DELETE 或清空缓存时

工作原理

java 复制代码
// 示例:一级缓存演示
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    
    // 第一次查询,会访问数据库
    User user1 = mapper.selectById(1L);
    
    // 第二次查询相同数据,直接从一级缓存获取
    User user2 = mapper.selectById(1L); // 不会访问数据库
    
    // 执行更新操作
    mapper.updateUser(user1);
    
    // 再次查询,缓存已失效,会访问数据库
    User user3 = mapper.selectById(1L); // 访问数据库
}

二级缓存

二级缓存是SqlSessionFactory级别,通过同一个SqlSessionFactory创建SqlSession查询的结果会被缓存;此后若再次执行相同的查询语句,结果就会从缓存中获取。(默认关闭)

基本特性

  • 默认关闭:需要手动开启
  • 作用范围:Mapper 级别的缓存,跨 SqlSession
  • 生命周期:只要不清理,一直存在
  • 失效情况:两次查询之间执行了任意的增删改,会使一级和二级缓存同时失效

如何开启

  1. 在核心配置文件(mybatis-config.xml)中,设置全局配置属性cacheEnabled="true",默认为true,不需要设置

    xml 复制代码
    <configuration>
    	<settings>
        	<!-- 默认为 true,通常无需显式配置 -->
        	<setting name="cacheEnabled" value="true"/>
    	</settings>
    </configuration>
  2. 在mapper.xml中声明使用缓存

    xml 复制代码
    <select id="selectUser" resultType="User" useCache="false">
    	SELECT * FROM user WHERE id = #{id}
    </select>
    <mapper namespace="com.example.UserMapper">
     	<cache /> <!-- 开启二级缓存 -->
    	 <select id="selectById" resultType="User" useCache="true">
    	 	SELECT * FROM user WHERE id = #{id}
     	</select>
    </mapper>
  3. 或注解方式配置

    java 复制代码
    @CacheNamespace(
    	eviction = LruCache.class,
    	flushInterval = 60000,
    	size = 512
    )
    public interface UserMapper {
    
    	@Options(useCache = true)
    	@Select("SELECT * FROM user WHERE id = #{id}")
    	User selectById(Long id);
    }
  4. 查询的数据所转换的实体类类型必须实现序列化的接口

    java 复制代码
    public class User implements Serializable {
     	private static final long serialVersionUID = 1L;
     	// ...
    }
  5. 二级缓存必须在SqlSession关闭或提交之后有效

对比

MyBatis缓存查询的顺序

  1. 先查询二级缓存,因为二级缓存中可能会有其他程序已经查出来的数据,可以拿来直接使用;
  2. 如果二级缓存没有命中,再查询一级缓存;
  3. 如果一级缓存也没有命中,则查询数据库;
  4. SqlSession关闭之后,一级缓存中的数据会写入二级缓存。

总结

  1. 不要用二级缓存,生产环境一般用redis替代,避免数据不一致的问题。
  2. 一级缓存只在单次sqlsession中生效。

参考:

http://www.cppcns.com/ruanjian/java/727879.html

https://developer.aliyun.com/article/1613160

以上为个人学习分享,如有问题,欢迎指出:)

相关推荐
小王不爱笑13210 小时前
MyBatis 执行流程源码级深度解析:从 Mapper 接口到 SQL 执行的全链路逻辑
数据库·sql·mybatis
弹简特11 小时前
【JavaEE18-后端部分】 MyBatis 入门第二篇:使用注解完成增删改查(含有参数传递底层原理)
spring boot·mybatis
小王不爱笑13212 小时前
SpringBoot 自动装配深度解析:从底层原理到自定义 starter 实战(含源码断点调试)
java·spring boot·mybatis
青槿吖15 小时前
SpringMVC通关秘籍(下):日期转换器、拦截器与文件上传的奇幻冒险
java·开发语言·数据库·sql·mybatis·状态模式
LSL666_19 小时前
BaseMapper——新增和删除
java·开发语言·mybatis·mybatisplus
摇滚侠19 小时前
IDEA 开发,Mybatis 中,@Insert 注解如何提示出列名
java·intellij-idea·mybatis
小王不爱笑13220 小时前
MyBatis-Plus 核心知识点
mybatis
码界奇点20 小时前
基于Spring MVC和MyBatis的妖气山视频管理系统设计与实现
java·spring·毕业设计·mvc·mybatis·源代码管理
indexsunny20 小时前
互联网大厂Java面试实战:从Spring Boot到微服务与Kafka的深度探讨
java·spring boot·junit·kafka·mybatis·hibernate·microservices
LSL666_21 小时前
5 MySQL驱动类选择与数据库连接 URL 时区配置
数据库·mysql·mybatis·mybatisplus