MyBatis 緩存機制詳解
MyBatis 提供了強大的緩存機制來提高數據庫訪問性能,主要包括一級緩存和二級緩存兩種。
一級緩存 (Local Cache)
特性:
- 默認開啟,作用域為 SqlSession 級別
- 同一個 SqlSession 中執行相同的 SQL 查詢時,會直接從緩存中獲取結果
- 執行 INSERT/UPDATE/DELETE 操作或調用
clearCache()
方法時會清空緩存
工作原理:
- 第一次查詢后將結果存入 SqlSession 的緩存
- 后續相同查詢直接從緩存獲取
- 任何更新操作都會清空當前 SqlSession 的緩存
示例:
SqlSession session = sqlSessionFactory.openSession();
try {// 第一次查詢,訪問數據庫User user1 = session.selectOne("getUserById", 1);// 第二次查詢,直接從一級緩存獲取User user2 = session.selectOne("getUserById", 1);// 執行更新操作,清空一級緩存session.update("updateUser", user1);// 需要再次訪問數據庫User user3 = session.selectOne("getUserById", 1);
} finally {session.close();
}
二級緩存 (Second Level Cache)
特性:
- 需要手動配置開啟,作用域為 Mapper 級別 (Namespace 級別)
- 多個 SqlSession 共享緩存數據
- 緩存數據可以持久化到磁盤或使用第三方緩存實現
配置方式:
- 在 mybatis-config.xml 中啟用二級緩存:
<settings><setting name="cacheEnabled" value="true"/>
</settings>
- 在 Mapper XML 中配置緩存:
<mapper namespace="com.example.UserMapper"><cache/>...
</mapper>
高級緩存配置:
<cacheeviction="FIFO"flushInterval="60000"size="512"readOnly="true"/>
eviction
:緩存回收策略 (LRU, FIFO, SOFT, WEAK)flushInterval
:刷新間隔(毫秒)size
:緩存對象數量readOnly
:是否只讀
注意事項:
- 二級緩存需要實體類實現 Serializable 接口
- 事務提交后(SqlSession關閉后)才會將數據存入二級緩存
- 多表操作可能導致臟讀問題
緩存執行順序
- 先查詢二級緩存
- 二級緩存未命中則查詢一級緩存
- 一級緩存未命中才查詢數據庫
自定義緩存
MyBatis 支持集成第三方緩存,如 Ehcache、Redis:
<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
緩存最佳實踐
- 查詢頻繁但更新少的表適合使用緩存
- 關聯查詢復雜的場景慎用二級緩存
- 對實時性要求高的數據考慮設置較短的 flushInterval
- 考慮使用只讀緩存提高性能
- 分布式環境建議使用集中式緩存(如Redis)
通過合理配置 MyBatis 緩存,可以顯著減少數據庫訪問,提高系統性能。