MyBatis 一級緩存實現詳解及使用注意事項


一級緩存介紹

在應用運行過程中,我們有可能在一次數據庫會話中,執行多次查詢條件完全相同的SQL,MyBatis提供了一級緩存的方案優化這部分場景,如果是相同的SQL語句,會優先命中一級緩存,避免直接對數據庫進行查詢,提高性能。具體執行過程如下圖所示。

img

每個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)); // 查詢數據庫
}

一級緩存工作流程

一級緩存執行的時序圖,如下圖所示。

img

總結

  1. MyBatis一級緩存的生命周期和SqlSession一致。
  2. MyBatis一級緩存內部設計簡單,只是一個沒有容量限定的HashMap,在緩存的功能性上有所欠缺。
  3. MyBatis的一級緩存最大范圍是SqlSession內部,有多個SqlSession或者分布式的環境下,數據庫寫操作會引起臟數據,所以建議設定緩存級別為Statement


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM