Mybatis 一級緩存、二級緩存
作者 : Stanley 羅昊
【轉載請注明出處和署名,謝謝!】
查詢緩存
首先,我們先看一下這個標題“查詢緩存”,那就說明跟增、刪、改是沒有任何關聯的,只有在查詢時,才會遇到緩存,增刪改不涉及!
查詢緩存目前Mybatis中提供了兩個,分別是:一級緩存、二級緩存;
一級緩存
先說一下一級緩存的范圍:同一個SqlSession對象,也就說,我們是同一個SqlSession對象,又要進行同樣的查詢操作,那么,我們就可以去緩存中獲取;
所以,SqlSession的緩存,是屬於一級緩存;
那,又有什么用呢?
比如,我們現在數據庫中有兩條數據,分別是張三跟李四;
我現在呢,要根據name來查詢張三這個人,首先說明一點,這是第一次去根據name來查詢張三,這個時候呢,我們就會去訪問數據庫,去獲取name是張三的數據,拿到張三后,它會把張三又放進了Sqlssion對象中去了,Sqlssion對象存在內存中;
也就是說,我們第一次查完后,我們會將張三這個數據從數據庫中獲取一下,獲取后放到緩存里面,此時的緩存就在內存里面,具體的來說,它就在Sqlsession對象里面;
上述操作如下圖:
如果,再有一次或再有N次來查詢這個張三,我就不需要去訪問數據庫了,因為我在緩存里面已經有了,如果你再要拿這個張三,直接直接從緩存里面去拿;
因此呢,我們可以發現,緩存可以減少數據庫的訪問;
我們都知道,數據庫的打開與關閉均比較費性能,所以,我們就不需要從數據庫中拿了,直接從緩存中去獲取就完事了,意思就是可以提高性能;
SqlSession對象清空機制
只要執行你commit(提交)這個方法,那么就會直接將SqlSession對象全部清空掉,一旦執行commit,就會清理我們的緩存對象;
上述如下圖:
首先,這些操作,我們不需要去手動的去編寫,我們僅需知道並了解即可,因為Mybatis默認了就開啟了一級緩存;
總結:
如果用相同的SqlSession對象查詢相同的數據,則只會在第一次查詢時發送Sql語句,並將這個查詢的結果放入到Sqlsession中(作為緩存存在);
后續再次查詢該同意的對象時,則直接從緩存中查詢該對象即可(即省略了數據庫的訪問)
二級緩存
首先,這個Mybatis自帶二級緩存;
也有三方提供的二級緩存;
Mybatis覺得緩存很重要,所以就自帶了一個緩存,但是,Mybatis必定不是搞緩存的,搞數據的,但是第三方公司給你提供了一些緩存,因為你mybatis做緩存這塊兒不是專業的;
我們可以回顧一下,一級緩存是同一個Sqlsession對象,那么二級緩存呢?
二級緩存是同一個在同一個namespace生成的mapper對象,重點是這個namespace;
也就是說,哪怕你生成了許多對象,只要你這個對象來自同一個namespace,它們就會共享同一個緩存;
什么是namespace,我在這里就不強調了,因為這個是mybatis入門必學的;
簡單點來說:
只要產生的xxxMapper對象來自於同一個namespace,則,這個對象共享二級緩存;
二級緩存的這個共享范圍,是同一個namespace產生的xxxMapper對象;
開啟緩存很簡單,如果你是boot項目的話,直接在你需要開啟的mapper.xml中加上一句話,來表示本namespace開啟了二級緩存:
<cache/>;
如果是ssm框架的話,需要在conf.xml中添加一些配置:
在這里,順便提一下,mybatis的二級緩存是屬於序列化,序列化的意思就是從內存中的數據傳到硬盤中,這個過程就是序列化;
反序列化意思就是相反而已;
也就是說,mybatis的二級緩存,實際上就是將數據放進了硬盤文件中去了;
實現序列化接口
如果你要使用mybatis的二級緩存,那么你除了要在你需要緩存的mappe.xml中開啟以外,你還需要實現序列化的接口,在你需要使用二級緩存的實體類中;
去實現這個 Serializable(序列化)接口即可;
現在呢,你僅僅的將Student類給序列化了,Student有父類、級聯屬性,它們是不會跟着被序列化的,所以光這些是不夠的;
其實很簡單,如果Student需要序列化,但是這個類中還有其他類的屬性,僅需將其他類也序列化即可!
比如學生類中繼承了父類,那么父類也需要實現Serializable這個接口進行序列化;
緩存時機
該序列化也序列化了,也已經在你需要進行緩存的mapper.xml文件中也開啟緩存了,但是如果你使用原生的SqlsessionFacotry(SSM\SpringBoot除外因為是集成好的不需要寫底層)去寫的時候會發現,緩存並沒有起效,而是關閉Session(session.close())才生效了;
這個其實就是mybatis的一個機制,其實很好理解;
比如,我現在去查詢張三,獲取張三數據之后我們需要經過序列化然后存貯到硬盤上,上面我也說過了,mybatis的二級緩存實際上就是將數據保存到硬盤上的某個文件中了,照這樣,每來一個新的對象,比如張三存進來了,李四也需要存,王五也需要,如果是存儲到硬盤上,那么就會用到IO技術,眾所周知,IO也是比較費性能,所以這個機制就是當你關閉session的時候,我們把這些張三、李四、王五這些數據一塊兒保存到硬盤上,而不是來一個保存一個這樣IO也受不了,所以就存在這樣的機制;