【Java-MyBatis】MyBatis 一级缓存和二级缓存的区别?
·

MyBatis 一级缓存与二级缓存的区别详解
🧠 一、缓存是什么?(类比故事)
想象你是个图书管理员(MyBatis),每次读者(应用程序)要借书(查询数据)时:
- 无缓存:每次都跑去书库(数据库)找书,效率低。
- 有缓存:把热门书放在前台小书架(缓存),下次直接取。
🔄 一级缓存(本地缓存)
- 作用域:
SqlSession级别(一次数据库会话) - 生命周期:
- 随
SqlSession创建而开启 - 随
SqlSession关闭或清空操作(clearCache())而销毁
- 随
- 默认开启:无需配置
- 工作原理:
SqlSession session1 = sqlSessionFactory.openSession(); User user1 = session1.selectOne("getUserById", 1); // 首次查数据库 User user2 = session1.selectOne("getUserById", 1); // 直接从缓存取 session1.close(); // 缓存销毁
📌 关键特点:
- 同一个 SqlSession 内有效(比如同一个 HTTP 请求)
- 更新操作自动清空缓存(如执行
insert/update/delete) - 类似 “私人书架”,仅自己能用
🔄 二级缓存(全局缓存)
- 作用域:
Mapper级别(跨 SqlSession) - 生命周期:
- 随应用启动初始化
- 随应用关闭或配置过期时间而失效
- 需手动开启:
SqlSession session2 = sqlSessionFactory.openSession();
User user2 = session2.selectOne(“getUserById”, 1); // 直接从二级缓存取
📌 **关键特点**:
1. **跨会话共享**(多个用户/请求共享数据)
2. **需序列化实体类**(实现 `Serializable` 接口)
3. 类似 "公共图书馆",所有人可访问
---
#### ⚖️ 核心区别总结
| **特性** | **一级缓存** | **二级缓存** |
|----------------|-------------------------------|-------------------------------|
| 作用域 | SqlSession 内部 | Mapper/Namespace 级别 |
| 生命周期 | 随 SqlSession 关闭而销毁 | 长期存在(直到配置过期) |
| 是否默认开启 | 是 | 需手动配置 |
| 数据共享 | 仅当前会话可用 | 跨会话共享 |
| 清空触发条件 | 执行 DML 操作或调用 clearCache() | 配置 flushInterval 或手动清除 |
---
#### 🚨 缓存问题与注意事项
1. **脏读风险**:
- 一级缓存:其他会话修改数据时,当前会话可能读到旧数据。
- 二级缓存:多个应用共享缓存时可能不一致(需配合 Redis 等分布式缓存)。
2. **适用场景**:
- 一级缓存:短时效、高频率查询(如用户权限校验)。
- 二级缓存:读多写少、全局共享数据(如商品分类列表)。
3. **强制刷新**:
```xml
<select ... flushCache="true"> <!-- 跳过缓存直接查库 -->
✅ 总结
一级缓存是 “会话级临时记忆”,二级缓存是 “应用级共享记忆”。
前者轻量但隔离性强,后者高效但需谨慎管理一致性。
生产环境中,二级缓存通常结合 Redis 实现分布式扩展。

更多推荐


所有评论(0)