首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

MyBatis 二級緩存深度解析:原理、配置與避坑指南

     編輯:Java 相關知識

二級緩存核心特性

  • 作用域:SqlSessionFactory 級別,多個 SqlSession 共享
  • 隔離單元:以 Mapper 的 namespace 劃分,不同 namespace 擁有獨立緩存空間
  • 觸發機制:相同 SQL 查詢優先命中緩存,未命中才查數據庫
  • 失效條件:任意 insert/update/delete 提交(commit())會清空該 namespace 下的二級緩存

配置啟用步驟

1. 全局開關 sqlMapConfig.xml

<setting name="cacheEnabled" value="true"/>  <!-- 默認即為 true -->

2. Mapper 級聲明 UserMapper.xml

<mapper namespace="com.example.mapper.UserMapper">
    <cache/>  <!-- 使用默認 PerpetualCache,LRU 淘汰,1024 引用,讀寫 -->
    <select id="findUserById" resultType="User" parameterType="int">
        select * from user where id = #{id}
    </select>
</mapper>

3. 實體類實現序列化

public class User implements Serializable {
    private static final long serialVersionUID = 1L;
    // 欄位、getter/setter...
}

原因:二級緩存數據可能被序列化至磁盤或網絡傳輸,必須實現 Serializable。

進階控制

場景配置說明
某查詢不走緩存<select useCache="false">強制每次查數據庫
增刪改不清空緩存<insert flushCache="false">慎用,可能導致髒讀

運行流程示例

SqlSession s1 = factory.openSession();
SqlSession s2 = factory.openSession();
SqlSession s3 = factory.openSession();

UserMapper m1 = s1.getMapper(UserMapper.class);
UserMapper m2 = s2.getMapper(UserMapper.class);
UserMapper m3 = s3.getMapper(UserMapper.class);

// 第一次查詢 → 查數據庫 → 寫入二級緩存
User u1 = m1.findUserById(1);
s1.close();  // 關鍵:close() 才會將數據提交至二級緩存

// 修改操作 → 清空二級緩存
User u = m3.findUserById(1);
u.setUsername("mmm");
m3.updateUser(u);
s3.commit();  // commit() 觸發緩存清空

// 第二次查詢 → 緩存已失效 → 重新查數據庫
User u2 = m2.findUserById(1);
s2.close();

常見誤區與最佳實踐

  1. 誤以為 openSession 即共享:必須先 close() 或 commit() 才會刷新至二級緩存。
  2. 忽略序列化:實體類未實現 Serializable 會拋出 NotSerializableException。
  3. 濫用 flushCache="false":高併發下極易產生髒讀,建議保持默認 true。
  4. 緩存粒度過大:按业务表拆分 Mapper namespace,避免無關表操作誤清緩存。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved