一級緩存介紹 在應用運行過程中,我們有可能在一次資料庫會話中,執行多次查詢條件完全相同的SQL,MyBatis提供了一級緩存的方案優化這部分場景,如果是相同的SQL語句,會優先命中一級緩存,避免直接對資料庫進行查詢,提高性能。具體執行過程如下圖所示。 每個SqlSession回話中會創建Execut ...
一級緩存介紹
在應用運行過程中,我們有可能在一次資料庫會話中,執行多次查詢條件完全相同的SQL,MyBatis提供了一級緩存的方案優化這部分場景,如果是相同的SQL語句,會優先命中一級緩存,避免直接對資料庫進行查詢,提高性能。具體執行過程如下圖所示。
每個SqlSession回話中會創建Executor執行器,每個Executor執行器中有一個Local Cache
。當用戶發起查詢時,MyBatis根據當前執行的語句生成MappedStatement
,在Local Cache進行查詢,如果緩存命中的話,直接返回結果給用戶,如果緩存沒有命中的話,查詢資料庫,結果寫入Local Cache
,最後返回結果給用戶。
一級緩存配置
我們來看看如何使用MyBatis一級緩存。開發者只需在MyBatis的配置文件中,添加如下語句,就可以使用一級緩存。共有兩個選項,SESSION
或者STATEMENT
,預設是SESSION
級別,即在一個MyBatis會話中執行的所有語句,都會共用這一個緩存。一種是STATEMENT
級別,可以理解為緩存只對當前執行的這一個Statement
有效。
<setting name="localCacheScope" value="SESSION"/>
一級緩存實驗
開啟一級緩存,範圍為會話級別,調用三次getStudentById
,代碼如下所示:
public void getStudentById() throws Exception {
SqlSession sqlSession = factory.openSession(true); // 自動提交事務
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
System.out.println(studentMapper.getStudentById(1)); // 查詢資料庫
System.out.println(studentMapper.getStudentById(1)); // 查詢緩存
System.out.println(studentMapper.getStudentById(1)); // 查詢緩存
}
public void addStudent() throws Exception {
SqlSession sqlSession = factory.openSession(true); // 自動提交事務
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
System.out.println(studentMapper.getStudentById(1)); // 查詢資料庫
System.out.println(studentMapper.addStudent(buildStudent())); // 更新數據
System.out.println(studentMapper.getStudentById(1)); // 查詢資料庫
sqlSession.close();
}
public void testLocalCacheScope() throws Exception {
SqlSession sqlSession1 = factory.openSession(true);
SqlSession sqlSession2 = factory.openSession(true);
StudentMapper studentMapper = sqlSession1.getMapper(StudentMapper.class);
StudentMapper studentMapper2 = sqlSession2.getMapper(StudentMapper.class);
System.out.println(studentMapper.getStudentById(1)); // 查詢資料庫
System.out.println(studentMapper.getStudentById(1)); // 查詢緩存
System.out.println(studentMapper2.updateStudentName("小岑",1)); // 更新數據
System.out.println(studentMapper.getStudentById(1)); // 查詢緩存,臟數據
System.out.println(studentMapper2.getStudentById(1)); // 查詢資料庫
}
一級緩存工作流程
一級緩存執行的時序圖,如下圖所示。
總結
- MyBatis一級緩存的生命周期和SqlSession一致。
- MyBatis一級緩存內部設計簡單,只是一個沒有容量限定的HashMap,在緩存的功能性上有所欠缺。
- MyBatis的一級緩存最大範圍是SqlSession內部,有多個SqlSession或者分散式的環境下,資料庫寫操作會引起臟數據,所以建議設定緩存級別為Statement。