Java面試經常問到Mybatis一級緩存和二級緩存,今天就給大家重點詳解Mybatis一級緩存和二級緩存原理與差別
Mybatis緩存
緩存就是記憶體中的資料,常常來自對資料庫查詢結果的儲存,使用緩存可以避免頻繁與資料庫進行互動,進而提高查詢響應速度。
MyBatis 提供了對緩存的支援,分為一級緩存和二級緩存,如下圖所示:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAnYldHL0FWby9mZvwFN4ETMfdHLkVGepZ2XtxSZ6l2clJ3LcV2Zh1Wa9M3clN2byBXLzN3btgHL9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsQTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5SOxAjN3EmZ2QjY0gTOwMmMzYzX0QjNwUTMyIzLclDMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.png)
我們先大緻了解下MyBatis一級緩存與MyBatis 二級緩存:
一級緩存:SqlSession級别的緩存,緩存的資料隻在SqlSession内有效。
二級緩存:mapper級别的緩存,同一個namespace公用這一個緩存,是以對SqlSession是共享的,二級緩存需要我們手動開啟。
下面我們再分别詳解兩者的原理與差別。
Mybatis一級緩存
1.為什麼需要Mybatis一級緩存
當我們使用Mybatis進行資料庫的操作時候,會建立一個SqlSession來進行一次資料庫的會話,會話結束則關閉SqlSession對象。
如果我們很有可能多次查詢完全相同的sql語句,每一次查詢都查詢一次資料庫,那查詢資料庫代價是比較大的,這會導緻系統的資源浪費。
為了解決這個問題,Mybatis對每一次會話都添加了緩存操作,不用相同的SQL每次都需要查詢資料庫,這就是Mybatis一級緩存的作用。
2.Mybatis一級緩存的實作
我們知道對SqlSession的操作,mybatis内部都是通過Executor來執行的,Executor的生命周期和SqlSession是一緻的。
Mybatis在Executor中建立了本地緩存(一級緩存),如下圖所示:
大緻的流程如下:
第一次查詢使用者id資訊,先去緩存中查詢是否有,如果沒有,從資料庫中查詢使用者資訊,得到使用者資訊後在将使用者資訊儲存到一級緩存中。
如果sqlSession去執行commit操作(插入、更新、删除),清空sqlSession中的一級緩存,保證緩存中始終儲存的是最新的資訊,避免髒讀。
第二次查詢使用者id資訊,先去緩存中查詢,如緩存中有,直接從緩存中擷取。
注意:兩次查詢須在同一個sqlsession中完成,否則将不會走mybatis的一級緩存。
在mybatis與spring進行整合開發時,事務控制在service中進行,重複調用兩次servcie将不會走一級緩存,因為在第二次調用時session方法結束,SqlSession就關閉了。
3.Mybatis一級緩存配置
mybatis一級緩存的範圍有SESSION和STATEMENT兩種,預設是SESSION。
如果不想使用一級緩存,可以把一級緩存的範圍指定為STATEMENT,這樣每次執行完一個Mapper中的語句後都會将一級緩存清除。
如果需要更改一級緩存的範圍,可以在Mybatis的配置檔案中,在下通過localCacheScope指定。
<setting name="localCacheScope" value="STATEMENT"/>
Mybatis二級緩存
1.為什麼需要Mybatis二級緩存?
MyBatis 一級緩存最大的共享範圍就是一個SqlSession内部,那麼如果多個 SqlSession 需要共享緩存,則需要開啟二級緩存。
2.Mybatis二級緩存的實作
開啟二級緩存後,會使用 CachingExecutor 裝飾 Executor,進入一級緩存的查詢流程前,先在 CachingExecutor 進行二級緩存的查詢,具體的工作流程如下所示。
二級緩存開啟後,同一個 namespace 下的所有操作語句,都影響着同一個 Cache,即二級緩存被多個 SqlSession 共享,是一個全局的變量。
當開啟緩存後,資料的查詢執行的流程就是 二級緩存 -> 一級緩存 -> 資料庫。
MyBatis 是預設關閉二級緩存的,因為對于增删改操作頻繁的話,那麼二級緩存形同虛設,每次都會被清空緩存。
Mybatis一級緩存與二級緩存的差別
1)一級緩存 Mybatis的一級緩存是指SQLSession,一級緩存的作用域是SQlSession, Myabits預設開啟一級緩存。