當前位置:
首頁 > 知識 > Spring+SpringMVC+MyBatis深入學習及搭建——MyBatis查詢緩存

Spring+SpringMVC+MyBatis深入學習及搭建——MyBatis查詢緩存


1.什麼是查詢緩存

mybatis提供查詢緩存,用於減輕資料庫壓力,提高資料庫性能。

mybatis提供一級緩存和二級緩存。

Spring+SpringMVC+MyBatis深入學習及搭建——MyBatis查詢緩存

一級緩存是SqlSession級別的緩存。在操作資料庫時需要構造sqlSession對象,在對象中有一個數據結構(HashMap)用於存儲緩存數據。不同的sqlSession之間的緩存數據區域(HashMap)是互相不影響的。

二級緩存是mapper級別的緩存,多個sqlSession去操作同一個Mapper的sql語句,多個sqlSession可以共用二級緩存,二級緩存是跨sqlSession的。

為什麼要用緩存?

如果緩存中有數據就不用從資料庫中獲取,大大提高系統性能。


2.一級緩存

2.1一級緩存工作原理

Spring+SpringMVC+MyBatis深入學習及搭建——MyBatis查詢緩存

第一次發起查詢用戶id為1的用戶信息,先去找緩存中是否有id為1的用戶信息,如果沒有,從資料庫查詢用戶信息。

得到用戶信息,將用戶信息存儲到一級緩存中。

如果sqlSession去執行commit操作(執行插入、更新、刪除),清空sqlSession中的一級緩存,這樣做的目的為了讓緩存中存儲的是最新的信息,避免臟讀。

第二次發去查詢用戶id為1的用戶信息,先去找緩存中是否有id為1的用戶信息,緩存中有,直接從緩存中獲取用戶信息。

2.2一級緩存測試

mybatis默認支持一級緩存,不需要在配置文件去配置。

按照上邊一級緩存原理步驟去測試。


@Test

public void testCache1() throws Exception{

SqlSession sqlSession=sqlSessionFactory.openSession();

UserMapper userMapper=sqlSession.getMapper(UserMapper.class);

//下邊查詢使用一個SqlSession

//第一次發起請求,查詢id為1的用戶

User user1=userMapper.findUserById(1);

System.out.println(user1);

//如果sqlSession去執行commit操作(執行插入、更新、刪除),清空sqlSession中的一級緩存,

//這樣做的目的是為了讓緩存中存儲的是最新的信息,避免臟讀。

//更新user1的信息

user1.setUsername("測試用戶22");

userMapper.updateUser(user1);

//執行commit操作去清空緩存

sqlSession.commit();

//第二次發起請求,查詢id為1的用戶

User user2=userMapper.findUserById(1);

System.out.println(user2);

sqlSession.close();

}

2.3一級緩存應用

正式開發,是將mybatis和spring進行整合開發,事務控制在service中。

一個service方法中包括很多Mapper方法調用。

service{

//開始執行時,開啟事務,創建SqlSession對象

//第一次調用mapper的方法findUserById(1)

//第二次調用mapper的方法findUserById(1),從一級緩存中取數據

//方法結束,sqlSession關閉

}

如果是執行兩次service調用查詢相同的用戶信息,不走一級緩存,因為session方法結束,sqlSession就關閉,一級緩存就清空。


3.二級緩存

3.1二級緩存原理

Spring+SpringMVC+MyBatis深入學習及搭建——MyBatis查詢緩存

首先開啟mybatis的二級緩存。

sqlSession1去查詢用戶id為1的用戶信息,查詢到用戶信息後悔講查詢數據存儲到二級緩存中。

如果sqlSession3去執行相同mapper下的sql,執行commit提交,會清空該mapper下的二級緩存區域的數據。

sqlSession2去查詢用戶id為1的用戶信息,去緩存中找是否存在數據,如果存在直接從緩存中取出數據。

二級緩存與一級緩存區別:二級緩存的範圍更大,多個sqlSession可以共享一個UserMapper的二級緩存區域。UserMapper有一個二級緩存區域(按namespace分),其它mapper也有自己的二級緩存區域(按namespace分)。

每個namespace的mapper都有一個二級緩存區域,兩個mapper的namespace如果相同,這兩個mapper執行sql查詢到的數據將存在相同的二級緩存區域中。

3.2開啟二級緩存

mybatis的二級緩存是mapper範圍級別,除了在SqlMapConfig.xml設置二級緩存的總開關,還要在具體的mapper.xml中開啟二級緩存。

在核心配置文件SqlMapConfig.xml中加入:



描述 允許值 默認值
cacheEnabled 對在此配置文件下的所有cache 進行全局性開/關設置。 true false false

Spring+SpringMVC+MyBatis深入學習及搭建——MyBatis查詢緩存

在UserMapper.xml中開啟二級緩存,UserMapper.xml下的sql執行完成後存儲在它的緩存區域(HashMap)。

Spring+SpringMVC+MyBatis深入學習及搭建——MyBatis查詢緩存

3.3調用pojo類實現序列化介面

Spring+SpringMVC+MyBatis深入學習及搭建——MyBatis查詢緩存

為了將緩存數據取出執行反序列劃操作,因為二級緩存數據存儲介質多種多樣,不一定在內存。可能在硬碟、遠程等。

3.4測試方法


@Test

public void testCache2() throws Exception{

SqlSession sqlSession1=sqlSessionFactory.openSession();

SqlSession sqlSession2=sqlSessionFactory.openSession();

SqlSession sqlSession3=sqlSessionFactory.openSession();

UserMapper userMapper1=sqlSession1.getMapper(UserMapper.class);

UserMapper userMapper2=sqlSession2.getMapper(UserMapper.class);

UserMapper userMapper3=sqlSession3.getMapper(UserMapper.class);

//第一次發起請求,查詢id為1的用戶

User user1=userMapper1.findUserById(1);

System.out.println(user1);

//這裡執行關閉操作,將sqlSession中的數據寫到二級緩存區域

sqlSession1.close();

//使用sqlSession3執行commit()操作

User user=userMapper3.findUserById(1);

user1.setUsername("Joanna");

userMapper3.updateUser(user);

//執行提交,清空UserMapper下邊的二級緩存

sqlSession3.commit();

sqlSession3.close();

//第二次發起請求,查詢id為1的用戶

User user2=userMapper2.findUserById(1);

System.out.println(user2);

sqlSession2.close();

}

3.5禁用二級緩存

在statement中設置useCache=false可以禁用當前select語句的二級緩存,即每次查詢都會發出sql,默認情況是true,即該sql使用二級緩存。