一憔维、緩存概述
mybatis
提供查詢緩存涛救,用于減輕數(shù)據(jù)庫的壓力,提高數(shù)據(jù)庫的性能业扒。mybatis
提供一級緩存和二級緩存检吆。一級緩存就是
SqlSession
級別的緩存。在操作數(shù)據(jù)庫時不要構(gòu)造SqlSession
對象程储,在對象中有一個數(shù)據(jù)結(jié)構(gòu)(HashMap
)用于存儲緩存數(shù)據(jù)蹭沛,不同的SqlSession
之間的緩存數(shù)據(jù)區(qū)域(HashMap
中)是互相不影響的。二級緩存是
mapper
級別的緩存章鲤,可以實現(xiàn)SqlSession
之間的共享摊灭。多個SqlSession
去操作同一個mapper
的sql
語句,多個SqlSession
去操作數(shù)據(jù)庫得到數(shù)據(jù)會緩存在二級緩存區(qū)域败徊,二級緩存是跨SqlSession
帚呼。為什么要用緩存?
如果緩存中有數(shù)據(jù)則不需要從數(shù)據(jù)庫中來獲取數(shù)據(jù)了,大大提高系統(tǒng)的性能煤杀。
二眷蜈、一級緩存
2.1 原理
第一次發(fā)起查詢用戶
id
為1的用戶信息,先去找緩存中是否有此信息沈自,如果沒有則從數(shù)據(jù)庫中查詢酌儒,得到此信息之后將其存儲到一級緩存中,而第二次查詢的時候發(fā)現(xiàn)緩存中有則不會去查數(shù)據(jù)庫枯途,直接從緩存中獲取即可忌怎。如果在兩次查詢之間
SqlSession
去執(zhí)行commit
操作(執(zhí)行插入、更新酪夷、刪除)呆躲,此時會清空SqlSession
中的一級緩存,那么第二次查詢在緩存中就找不到數(shù)據(jù)了捶索,需要從數(shù)據(jù)庫中查詢插掂,這樣做的目的就是避免臟數(shù)據(jù),讓緩存中存儲的是最新信息腥例。
2.2 測試(工程mybatis12
)
mybatis默認(rèn)支持一級緩存辅甥,不需要在配置文件中開啟。按照上面的一級緩存的原理步驟去測試燎竖。
UserMapperTest.java
//一級緩存測試
@Test
public void testCache1() throws Exception{
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//下面兩次查詢使用的是同一個SqlSession
//第一次發(fā)起請求璃弄,查詢id為1的用戶
User user1 = userMapper.findUserById(1);
System.out.println(user1);
//第二次發(fā)起請求,查詢id為1的用戶
User user2 = userMapper.findUserById(1);
System.out.println(user1);
sqlSession.close();
}
此時查詢結(jié)果為:
可以看到兩次查詢只是發(fā)出了一條
sql
語句构回。此時我們在兩次查詢之間加入更新操作:
//一級緩存測試
@Test
public void testCache1() throws Exception{
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//下面兩次查詢使用的是同一個SqlSession
//第一次發(fā)起請求夏块,查詢id為1的用戶
User user1 = userMapper.findUserById(1);
System.out.println(user1);
//更新user1的信息,清空一級緩存
user1.setUsername("王五");
userMapper.updateUser(user1);
//執(zhí)行commit操作才會情況緩存
sqlSession.commit();
//第二次發(fā)起請求纤掸,查詢id為1的用戶
User user2 = userMapper.findUserById(1);
System.out.println(user1);
sqlSession.close();
}
此時的查詢結(jié)果為:
這里我們發(fā)現(xiàn)在第二次查詢的時候也是發(fā)出了
sql
語句脐供,因為緩存已經(jīng)被清空了。
2.3 應(yīng)用
在正式開發(fā)中借跪,mybatis
會和spring
進(jìn)行整合開發(fā)政己,事務(wù)控制是在service
上面,一個service
類的方法中包括很多mapper
方法的調(diào)用掏愁,如:
service{
//1.開始執(zhí)行時歇由,開啟事務(wù),創(chuàng)建SqlSession對象
//2.第一次調(diào)用mapper方法findUserById(1)
//....
//3.第二次調(diào)用mapper方法findUserById(1)果港,此時從緩存中取
//4.方法結(jié)束沦泌,SqlSession關(guān)閉
}
注意:這里我們可以看到事務(wù)關(guān)閉是在service
方法執(zhí)行完之后,而不是像上面測試那樣查詢完了就關(guān)閉了辛掠,這樣就可以利用一級緩存谢谦。當(dāng)然如果是兩個service
方法則不能實現(xiàn)了,如果還想實現(xiàn)緩存則需要用到二級緩存了。