文章目錄
- 1?? 一級緩存(Local Cache)
- 📌 定義
- 🚀 示例代碼
- 2?? 二級緩存(Global Cache)
- 📌 定義
- 🚀 使用方式
- 3?? 一級緩存 vs. 二級緩存 📊
- 4?? 數據共享問題
- 🔸 數據一致性問題
- 🔸 并發訪問問題
- 🔸 分布式環境中的緩存共享
- 5?? 總結 🚀
MyBatis 提供了強大的緩存機制,以提高數據庫查詢性能。緩存主要分為 一級緩存 和 二級緩存,它們分別應用于不同的范圍和場景。
1?? 一級緩存(Local Cache)
📌 定義
- 作用范圍:SqlSession 級別
- 存儲位置:SqlSession 內存中
- 默認開啟
- 失效條件:
- SqlSession 關閉
- 執行
insert
、update
、delete
操作 - 執行
select
時手動刷新緩存sqlSession.clearCache()
- 查詢不同的 SQL 語句
🚀 示例代碼
SqlSession sqlSession1 = sqlSessionFactory.openSession();
UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
User user1 = mapper1.getUserById(1); // 第一次查詢,數據從數據庫加載
User user2 = mapper1.getUserById(1); // 第二次查詢,數據從緩存獲取
sqlSession1.close();
2?? 二級緩存(Global Cache)
📌 定義
- 作用范圍:Mapper(Namespace)級別,多 SqlSession 共享
- 存儲位置:MyBatis 全局級別緩存,通常存儲在
PerpetualCache
- 默認關閉,需要手動開啟
- 失效條件:
- 執行
insert
、update
、delete
操作后,緩存會自動清除 - 直接操作數據庫
- 執行
🚀 使用方式
- 開啟二級緩存(在
mybatis-config.xml
或mapper.xml
中設置):
<settings><setting name="cacheEnabled" value="true"/>
</settings>
- 在 Mapper 配置中啟用緩存
<cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"/>
eviction="LRU"
:最近最少使用的緩存清理策略flushInterval="60000"
:60 秒自動刷新緩存size="512"
:最大緩存 512 個對象readOnly="true"
:只讀,提高并發效率
- 示例代碼
SqlSession sqlSession1 = sqlSessionFactory.openSession();
UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
User user1 = mapper1.getUserById(1);
sqlSession1.close(); // 數據寫入二級緩存SqlSession sqlSession2 = sqlSessionFactory.openSession();
UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
User user2 = mapper2.getUserById(1); // 從二級緩存讀取數據
sqlSession2.close();
3?? 一級緩存 vs. 二級緩存 📊
對比項 | 一級緩存 | 二級緩存 |
---|---|---|
作用范圍 | SqlSession | Mapper(Namespace)級別,多 SqlSession 共享 |
默認開啟 | ? 是 | ? 否(需手動開啟) |
失效條件 | SqlSession 關閉、增刪改操作 | 增刪改操作、數據庫更新、緩存超時 |
適用場景 | 單個會話內查詢優化 | 適用于多個 SqlSession 共享數據 |
4?? 數據共享問題
二級緩存的主要作用之一是跨 SqlSession 共享數據,但也會引發一些問題:
🔸 數據一致性問題
- 由于二級緩存存儲在 Mapper 級別,數據修改后不會立即更新緩存,可能導致數據不一致。
- 解決方案:
- 使用事務控制,確保數據庫更新后及時刷新緩存。
- 定期刷新緩存,通過
flushInterval
機制自動更新。 - 禁用二級緩存,對于高實時性數據建議不使用。
🔸 并發訪問問題
- 默認情況下,MyBatis 二級緩存是 readOnly,多個線程訪問時不會有并發問題。
- 如果設置
readOnly="false"
,則需要考慮線程安全問題。
🔸 分布式環境中的緩存共享
- 單機應用:二級緩存可以有效減少數據庫訪問,提高性能。
- 分布式應用:多個服務實例可能無法共享 MyBatis 二級緩存,導致緩存失效或不一致。
- 解決方案:
- 采用 Redis、EhCache 等第三方分布式緩存代替 MyBatis 內置緩存。
- 結合 消息隊列(MQ) 機制,在數據更新時廣播清除緩存。
5?? 總結 🚀
? 一級緩存 適用于 單個 SqlSession,默認開啟,生命周期短。
? 二級緩存 適用于 多個 SqlSession 共享,默認關閉,需要手動開啟。
? 數據一致性問題 是二級緩存的關鍵挑戰,需謹慎使用。
? 分布式架構下建議使用第三方緩存(如 Redis)以實現緩存共享。
? 適用于 讀多寫少 的場景,如查詢熱門數據、字典數據等。