SqlSessionFactory 級別,多個 SqlSession 共享namespace 劃分,不同 namespace 擁有獨立緩存空間insert/update/delete 提交(commit())會清空該 namespace 下的二級緩存sqlMapConfig.xml<setting name="cacheEnabled" value="true"/> <!-- 默認即為 true -->
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>
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();
close() 或 commit() 才會刷新至二級緩存。Serializable 會拋出 NotSerializableException。true。