查詢緩存
1.什麼是查詢緩存
mybatis提供查詢緩存,用於減輕數據壓力,提升數據庫性能。
mybaits提供一級緩存,和二級緩存。
java
緩存模式圖如圖mysql
一級緩存是SqlSession級別的緩存。在操做數據庫時須要構造 sqlSession對象,在對象中有一個數據結構(HashMap)用於存儲緩存數據。不一樣的sqlSession之間的緩存數據區域(HashMap)是互相不影響的。
二級緩存是mapper級別的緩存,多個SqlSession去操做同一個Mapper的sql語句,多個SqlSession能夠共用二級緩存,二級緩存是跨SqlSession的。
爲何要用緩存?
若是緩存中有數據就不用從數據庫中獲取,大大提升系統性能。
2.一級緩存
2.1一級緩存工做原理
spring
如圖sql
第一次發起查詢用戶id爲1的用戶信息,先去找緩存中是否有id爲1的用戶信息,若是沒有,從數據庫查詢用戶信息。
獲得用戶信息,將用戶信息存儲到一級緩存中。
若是sqlSession去執行commit操做(執行插入、更新、刪除),清空SqlSession中的一級緩存,這樣作的目的爲了讓緩存中存儲的是最新的信息,避免髒讀。
第二次發起查詢用戶id爲1的用戶信息,先去找緩存中是否有id爲1的用戶信息,緩存中有,直接從緩存中獲取用戶信息。
2.2一級緩存測試
mybatis默認支持一級緩存,不須要在配置文件去配置。
按照上邊一級緩存原理步驟去測試。
測試1:數據庫
//測試一級緩存 @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.getUsername()); //第二次發起請求,查詢id爲1的用戶 User user2 = userMapper.findUserById(1); System.out.println(user2.getUsername()); sqlSession.close(); }
測試結果和輸出日誌:緩存
DEBUG [main] - Opening JDBC Connection DEBUG [main] - Created connection 19140890. DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.Connection@124111a] DEBUG [main] - ==> Preparing: SELECT * FROM USER WHERE id=? DEBUG [main] - ==> Parameters: 1(Integer) DEBUG [main] - <== Total: 1 張三 張三 DEBUG [main] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.Connection@124111a] DEBUG [main] - Closing JDBC Connection [com.mysql.jdbc.Connection@124111a] DEBUG [main] - Returned connection 19140890 to pool.
能夠看到第二次取user2的時候沒有發出sql查詢,說明調用了一級緩存
接下來測試看看在中間執行了增刪改查的時候會不會清空一級緩存數據結構
//測試一級緩存 @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.getUsername()); /*若是sqlSession去執行commit操做(執行插入、更新、刪除), * 清空SqlSession中的一級緩存,這樣作的目的爲了讓緩存中存儲的是最新的信息,避免髒讀。 */ //更新user1的信息 user1.setUsername("測試用戶22"); userMapper.updateUser(user1); //執行commit操做去清空緩存 sqlSession.commit(); //第二次發起請求,查詢id爲1的用戶 User user2 = userMapper.findUserById(1); System.out.println(user2.getUsername()); sqlSession.close(); }
測試結果和輸出日誌:mybatis
DEBUG [main] - Opening JDBC Connection DEBUG [main] - Created connection 6778431. DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.Connection@676e3f] DEBUG [main] - ==> Preparing: SELECT * FROM USER WHERE id=? DEBUG [main] - ==> Parameters: 1(Integer) DEBUG [main] - <== Total: 1 張三 DEBUG [main] - ==> Preparing: update user set username=?,birthday=?,sex=?,address=? where id=? DEBUG [main] - ==> Parameters: 測試用戶2(String), 2015-06-07(Date), 男(String), 河南焦做(String), 1(Integer) DEBUG [main] - <== Updates: 1 DEBUG [main] - Committing JDBC Connection [com.mysql.jdbc.Connection@676e3f] DEBUG [main] - ==> Preparing: SELECT * FROM USER WHERE id=? DEBUG [main] - ==> Parameters: 1(Integer) DEBUG [main] - <== Total: 1 測試用戶2 DEBUG [main] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.Connection@676e3f] DEBUG [main] - Closing JDBC Connection [com.mysql.jdbc.Connection@676e3f] DEBUG [main] - Returned connection 6778431 to pool.
發現第二次取數據時發出了sql請求,說明執行增刪改查的時候會清空一級緩存
2.3一級緩存應用
正式開發,是將mybatis和spring進行整合開發,事務控制在service中。
一個service方法中包括 不少mapper方法調用。
service{
//開始執行時,開啓事務,建立SqlSession對象
//第一次調用mapper的方法findUserById(1)
//第二次調用mapper的方法findUserById(1),從一級緩存中取數據
//方法結束,sqlSession關閉
}
app
若是是執行兩次service調用查詢相同 的用戶信息,不走一級緩存,由於service方法結束,sqlSession就關閉,一級緩存就清空。這個時候就須要使用二級緩存,詳情看下一篇總結性能