MyBatis(4)一級緩存,二級緩存

MyBatis的緩存,包括一級緩存,二級緩存。

什么是一級緩存?

一級緩存指的就是sqlsession,在sqlsession中有一個數據區域,是map結構,這個區域就是一級緩存區域。一級緩存中的key是由sql語句、條件、statement等信息組成一個唯一值。一級緩存中的value,就是查詢出的結果對象。

什么是二級緩存?

二級緩存指的就是同一個namespace下的mapper,二級緩存中,也有一個map結構,這個區域就是一級緩存區域。一級緩存中的key是由sql語句、條件、statement等信息組成一個唯一值。一級緩存中的value,就是查詢出的結果對象。

一級緩存是默認使用的。

二級緩存需要手動開啟。

MyBatis緩存框架圖

MyBatis緩存框架圖

一級緩存原理圖

代碼測試:

 /**
 * 測試一級緩存
 * @throws Exception
 */
@Test
public void testSelectStudentById() throws Exception {
    SqlSession session1 = sqlSessionFactory.openSession();
    // 拿到代理對象
    StudentMapper mapper = session1.getMapper(StudentMapper.class);
    //第一次查詢id為1的Student的信息
    Student student1 = mapper.selectStudentById(1);
    System.out.println(student1);
    //第二次查詢時,發現緩存中有id為1的Student的信息,于是從緩存中讀取
    Student student2 = mapper.selectStudentById(1);
    System.out.println(student2);
    session1.close();
}

然后debug看一下

再回頭看一下上面一級緩存原理圖中間那一部分,當修改刪除更新時commit,會自動清空緩存

代碼測試:

 /**
 * 測試一級緩存
 * @throws Exception
 */
@Test
public void testSelectStudentById() throws Exception {
    SqlSession session1 = sqlSessionFactory.openSession();
    // 拿到代理對象
    StudentMapper mapper = session1.getMapper(StudentMapper.class);
    //第一次查詢id為1的Student的信息
    Student student1 = mapper.selectStudentById(1);
    System.out.println(student1);
    //更新操作
    student1.setName("RonaldoWang");
    mapper.updateStudent(student1);
    //commit()就會清空緩存
    session1.commit();
    //第二次查詢時,發現緩存中有id為1的Student的信息,于是從緩存中
    Student student2 = mapper.selectStudentById(1);
    System.out.println(student2);
    session1.close();
}

測試結果:


二級緩存原理圖

看起來二級緩存與一級緩存相似,只是二級緩存的范圍更廣,區域劃分是namespace,而一級緩存是在sqlsession里面。

1.開啟二級緩存

第一步:總開關開啟,需要在sqlMapConfig.xml中通過settings標簽開啟,默認它就是開啟的,但還是寫上去比較好,容易閱讀吧。

第二步:在Mapper.xml下namespace中開啟自己的開關

第三步:在PO類中實現序列化操作。

)

之所以需要實現序列化接口,是因為方便反序列化,二級緩存的區域不一定只是在內存中,也有可能在硬盤中。

測試代碼:

/**
 * 測試二級緩存
 * @throws Exception
 */
@Test
public void testSelectStudentById() throws Exception {
    SqlSession session1 = sqlSessionFactory.openSession();
    SqlSession session2 = sqlSessionFactory.openSession();
    SqlSession session3 = sqlSessionFactory.openSession();

    StudentMapper mapper1 = session1.getMapper(StudentMapper.class);
    StudentMapper mapper2 = session2.getMapper(StudentMapper.class);
    StudentMapper mapper3 = session2.getMapper(StudentMapper.class);
    
    Student student1 = mapper1.selectStudentById(1);
    System.out.println(student1);
    //這里close很關鍵,在二級緩存中,close()會將數據放到二級緩存中
    session1.close();
    Student student3 = mapper3.selectStudentById(1);
    System.out.println(student3);
    session3.close();
}

測試結果:


上面代碼中session2,和mapper2還沒有用到,這里可以用mapper2給數據更新一下,看看是否會將緩存清空?

測試代碼

/**
 * 測試二級緩存
 * @throws Exception
 */
@Test
public void testSelectStudentById() throws Exception {
    SqlSession session1 = sqlSessionFactory.openSession();
    SqlSession session2 = sqlSessionFactory.openSession();
    SqlSession session3 = sqlSessionFactory.openSession();

    StudentMapper mapper1 = session1.getMapper(StudentMapper.class);
    StudentMapper mapper2 = session2.getMapper(StudentMapper.class);
    StudentMapper mapper3 = session3.getMapper(StudentMapper.class);
    
    Student student1 = mapper1.selectStudentById(1);
    System.out.println(student1);
    //這里close很關鍵,在二級緩存中,close()會將數據放到二級緩存中
    session1.close();
    
    
    Student student2 = mapper2.selectStudentById(1);
    student2.setName("小六子");
    mapper2.updateStudent(student2);
    session2.commit();
    session2.close();
    
    
    Student student3 = mapper3.selectStudentById(1);
    System.out.println(student3);
    session3.close();
}

測試結果:


圈出來的看看就能理解了。

禁用緩存

)

刷新緩存

刷新緩存在select語句中默認是false

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容