MyBatis一级缓存与二级缓存详解
一级缓存:工作原理与应用
1. 什么是一级缓存? 一级缓存是作用于 MyBatis SqlSession
会话级别的缓存。其核心思想是在同一个会话内,对相同的查询只访问数据库一次,而是直接从缓存中获取结果。
2. 一级缓存的特性
- 自动启用: 无需任何额外配置,一级缓存默认启用。
- 基于会话: 一级缓存的生命周期与
SqlSession
相同,SqlSession
关闭后缓存失效。 - 缓存失效条件: 在以下情况下,一级缓存会失效:
- 执行
INSERT
、UPDATE
或DELETE
操作。 - 手动清空缓存,例如调用
SqlSession.clearCache()
。 - 执行不同的查询。
- 执行
3. 代码示例
SqlSession session = sqlSessionFactory.openSession();
User user1 = session.selectOne("com.example.mapper.UserMapper.selectUser", 1);
User user2 = session.selectOne("com.example.mapper.UserMapper.selectUser", 1);
System.out.println(user1 == user2); // true
上述代码中,两次查询返回的是同一个对象,因为结果被缓存了。
4. 应用场景 一级缓存适用于短生命周期的操作,例如一个请求内多次查询相同数据时。
二级缓存:原理与配置
1. 什么是二级缓存? 二级缓存是作用于 MyBatis 全局范围的缓存。与一级缓存不同,它的缓存对象可以在多个 SqlSession
间共享。
2. 二级缓存的特性
- 跨会话共享: 缓存对象可以在多个
SqlSession
间共享。 - 可扩展性: 支持第三方缓存框架(如 EhCache、Redis)。
- 手动配置: 需要在 MyBatis 配置文件或注解中启用。
3. 二级缓存的配置方法
- 启用全局缓存 在
mybatis-config.xml
中设置:
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
- Mapper 配置缓存 在对应的 Mapper XML 文件中添加:
<cache/>
或者通过注解方式:
@CacheNamespace
public interface UserMapper {
// 方法声明
}
- 使用第三方缓存库 例如,配置 EhCache:
- 在
mybatis-config.xml
中指定缓存类:<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
- 配置
ehcache.xml
:<ehcache> <cache name="com.example.mapper.UserMapper" maxEntriesLocalHeap="1000" timeToLiveSeconds="60"/> </ehcache>
4. 二级缓存的使用示例
SqlSession session1 = sqlSessionFactory.openSession();
User user1 = session1.selectOne("com.example.mapper.UserMapper.selectUser", 1);
session1.close();
SqlSession session2 = sqlSessionFactory.openSession();
User user2 = session2.selectOne("com.example.mapper.UserMapper.selectUser", 1);
session2.close();
System.out.println(user1 == user2); // true
在上述代码中,不同的会话间共享了同一个缓存对象。
缓存的优缺点与注意事项
1. 优点
- 性能提升: 减少重复查询和数据库交互。
- 降低数据库压力: 缓存机制在高并发环境下尤为重要。
2. 局限性
- 缓存一致性问题: 数据库更新后缓存可能过时。
- 内存开销: 缓存占用系统内存,需合理设置缓存策略。
3. 实践建议
- 对于频繁变化的数据,谨慎启用缓存。
- 合理设置缓存过期时间,确保数据及时更新。
- 使用 Redis 等分布式缓存框架时,需要处理分布式锁和缓存雪崩问题。
结论
MyBatis 的一级缓存和二级缓存机制是提升性能的重要手段。一级缓存简单易用,适合短生命周期的会话操作;二级缓存配置灵活,适合共享性强的场景。在实际应用中,应根据具体需求选择合适的缓存方案,并通过合理的配置优化缓存效果。