開篇
mybatis緩存特點和hibernate緩存特點是及其相像,本篇博客通過實踐簡單的瞭解一下mybatis的一級二級緩存。
一級
特點:
一級緩存默認開啓
生命週期同sqlsession
sqlsession間緩存不共享
sqlsession關閉或執行sqlsession.commit() 時一級緩存清空
二級
概念說明:和hibernate不同,mybatis的二級緩存不是以sqlsessionfactory爲單位的,而是以mapper.xml中的namespace爲單位劃分的,也就是兩個mapper的namespace如果相同他們使用的就是同一個二級緩存。
特點:
默認不開啓,需手工配置
可多個sqlsession共享
如果某個session執行commit(),則該mappe下的二級緩存數據清空
二級緩存實例
一、開啓二級緩存
1、全局配置文件,settings中添加
<setting name="cacheEnabled" value="true"/> |
2、在mapper.xml中開啓,因爲二級緩存是以mapper爲單位的,所以要在具體的mapper.xml中開啓
<!-- 開啓本mapper的namespace下的二緩存 --> <cache/> |
配置原理:mybatis提供了一個cache接口,並且自身提供了一套實現,在mapper.xml中添加<cache/>的配置默認使用的是mybatis自身的緩存實現,如下圖:
如果要在mybatis中使用其他的第三方緩存比如ehcache,只需要在mapper中修改該配置即可。
<!-- 開啓本mapper的namespace下的二緩存 type:指定cache接口的實現類的類型,mybatis默認使用PerpetualCache 要和ehcache整合,需要配置type爲ehcache實現cache接口的類型 --> <cache type="org.mybatis.caches.ehcache.EhcacheCache"/> |
二、序列化被緩存的pojo類,因爲二級緩存數據的存儲介質不定。當取出二級緩存時執行反序列化操作。
三、測試
1、多個sqlsession共享
測試代碼:
// 二級緩存測試 @Test public void testCache2() throws Exception { SqlSession sqlSession1 = sqlSessionFactory.openSession(); SqlSession sqlSession2 = sqlSessionFactory.openSession();
// 創建代理對象 UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class); // 第一次發起請求,查詢id爲1的用戶 User user1 = userMapper1.findUserById(1); System.out.println(user1);
//這裏執行關閉操作,將sqlsession中的數據寫到二級緩存區域 sqlSession1.close();
UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class); // 第二次發起請求,查詢id爲1的用戶 User user2 = userMapper2.findUserById(1); System.out.println(user2); sqlSession2.close();
} |
跟蹤結果:第一個請求發出了sql語句,緩存命中率0.0。第二次請求沒有發出sql,緩存命中率0.5(表示一共發出兩次請求,一次使用來緩存)。
2、mapper中的某個sqlsession執行commit(),二級緩存清空
測試代碼:
// 二級緩存測試 @Test public void testCache2() throws Exception { SqlSession sqlSession1 = sqlSessionFactory.openSession(); SqlSession sqlSession2 = sqlSessionFactory.openSession(); SqlSession sqlSession3 = sqlSessionFactory.openSession();
// 創建代理對象 UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class); // 第一次發起請求,查詢id爲1的用戶 User user1 = userMapper1.findUserById(1); System.out.println(user1); //這裏執行關閉操作,將sqlsession中的數據寫到二級緩存區域 sqlSession1.close();
//使用sqlSession3執行commit()操作 UserMapper userMapper3 = sqlSession3.getMapper(UserMapper.class); User user = userMapper3.findUserById(1); user.setUsername("張明明"); userMapper3.updateUser(user); //執行提交,清空UserMapper下邊的二級緩存 sqlSession3.commit(); sqlSession3.close();
UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class); // 第二次發起請求,查詢id爲1的用戶 User user2 = userMapper2.findUserById(1); System.out.println(user2); sqlSession2.close();
} |
跟蹤結果:userMapper1第一次查詢發出sql,userMapper3查詢時沒有發出sql,修改提交後,userMapper2查詢時再次發出sql。
其他介紹
1、開啓二級緩存時在mapper.xml中進行了配置,這樣該mapper下的所有查詢都開啓了緩存,但是對更新頻率較高數據的查詢沒有必要開啓緩存,可以在對應的statement中使用useCache="false",這樣針對該條sql的緩存就會關閉。