mybatis缓存

MyBatis 缓存机制可以提高数据库查询的性能,减少数据库的访问次数。它分为一级缓存二级缓存


1. 一级缓存(Local Cache)

特点

  • 默认开启,作用范围是 同一个 SqlSession

  • 当查询相同的 SQL 语句并且参数相同时,MyBatis 会直接从缓存中取数据,而不是再次查询数据库。

  • SqlSession 关闭或提交事务后,一级缓存会被清空

示例

SqlSession sqlSession1 = sqlSessionFactory.openSession();
UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);

// 第一次查询,数据从数据库获取
User user1 = userMapper1.getUserById(1);
System.out.println(user1);

// 第二次查询,相同 SQL 语句和参数,数据从缓存获取
User user2 = userMapper1.getUserById(1);
System.out.println(user2);

sqlSession1.close(); // 关闭后缓存失效

一级缓存失效情况

  1. 不同的 SqlSession:MyBatis 的一级缓存是 SqlSession 级别的,不同的 SqlSession 互不影响。

  2. 执行 sqlSession.commit()sqlSession.close():事务提交或关闭后,缓存会被清空。

  3. 执行 sqlSession.clearCache():手动清除缓存。

  4. 执行 updateinsertdelete 语句:数据被修改后,缓存会失效,以防止脏数据。


2. 二级缓存(Global Cache)

特点

  • 需要手动开启,作用范围是 同一个 Mapper(Namespace)

  • 多个 SqlSession 共享 该缓存,提高查询性能。

  • 缓存的数据会被序列化,所以返回的对象需要实现 Serializable 接口。

  • 缓存默认存储在内存中,也可以集成 Redis、EhCache 等缓存框架。

开启二级缓存

  1. mybatis-config.xml 中开启全局缓存

<configuration>
    <settings>
        <setting name="cacheEnabled" value="true"/>
    </settings>
</configuration>
  1. 在 Mapper 文件(UserMapper.xml)中开启缓存

<cache eviction="LRU" flushInterval="60000" size="512" readOnly="false"/>
  • eviction="LRU":缓存淘汰策略,支持 LRU(最近最少使用)、FIFO(先进先出)、SOFT(软引用)、WEAK(弱引用)。

  • flushInterval="60000":缓存刷新时间(单位:毫秒)。

  • size="512":缓存的最大对象数。

  • readOnly="false":是否只读,如果设为 true,所有线程共享数据,不能修改,否则可能会出现并发问题。

  1. User 类必须实现 Serializable

public class User implements Serializable {
    private static final long serialVersionUID = 1L;
    private Integer id;
    private String name;
}

二级缓存示例

SqlSession sqlSession1 = sqlSessionFactory.openSession();
UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
User user1 = userMapper1.getUserById(1);
sqlSession1.close(); // 关闭 SqlSession,数据进入二级缓存

SqlSession sqlSession2 = sqlSessionFactory.openSession();
UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);
User user2 = userMapper2.getUserById(1); // 这次查询会从二级缓存获取
sqlSession2.close();

二级缓存失效情况

  1. Mapper 没有开启 <cache/> 配置

  2. 查询的对象未实现 Serializable

  3. sqlSession.commit() 或执行 updateinsertdelete 语句后,缓存会被清空

  4. 手动调用 sqlSession.clearCache()


3. MyBatis 缓存 vs Redis

对比项MyBatis 二级缓存Redis
作用范围当前 Mapper(Namespace)跨应用、全局共享
存储位置JVM 内存独立的 Redis 服务器
数据存储对象序列化存储key-value 形式存储
支持集群不支持支持
数据持久化关闭进程后丢失支持持久化
适用场景小规模项目分布式、高并发场景

推荐方案

  • 小型项目:使用 MyBatis 二级缓存即可,提高查询性能。

  • 大型项目(分布式、微服务架构):推荐使用 Redis 缓存方案,保证高可用性和扩展性。


4. 整合 MyBatis 和 Redis

如果要用 Redis 作为 MyBatis 的二级缓存,可以使用 mybatis-redis 插件:

<dependency>
    <groupId>org.mybatis.caches</groupId>
    <artifactId>mybatis-redis</artifactId>
    <version>1.0.0</version>
</dependency>

配置 UserMapper.xml

<cache type="org.mybatis.caches.redis.RedisCache"/>

配置 Redis

mybatis-config.xml 添加 Redis 相关配置:

<settings>
    <setting name="cacheEnabled" value="true"/>
</settings>

这样,MyBatis 的查询数据就会存储在 Redis 缓存中,提高查询效率。


总结

缓存级别默认开启作用范围清空时机特点
一级缓存SqlSession 级别SqlSession 关闭、事务提交、执行增删改开销小,自动管理
二级缓存Mapper 级别事务提交、执行增删改、手动清除需要手动开启,可用 Redis
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值