天天看點

Mybatis 一級緩存和二級緩存原理差別

Java面試經常問到Mybatis一級緩存和二級緩存,今天就給大家重點詳解Mybatis一級緩存和二級緩存原理與差別

Mybatis緩存

緩存就是記憶體中的資料,常常來自對資料庫查詢結果的儲存,使用緩存可以避免頻繁與資料庫進行互動,進而提高查詢響應速度。

MyBatis 提供了對緩存的支援,分為一級緩存和二級緩存,如下圖所示:

Mybatis 一級緩存和二級緩存原理差別

我們先大緻了解下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中建立了本地緩存(一級緩存),如下圖所示:

Mybatis 一級緩存和二級緩存原理差別
大緻的流程如下:

第一次查詢使用者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 進行二級緩存的查詢,具體的工作流程如下所示。

Mybatis 一級緩存和二級緩存原理差別

二級緩存開啟後,同一個 namespace 下的所有操作語句,都影響着同一個 Cache,即二級緩存被多個 SqlSession 共享,是一個全局的變量。

當開啟緩存後,資料的查詢執行的流程就是 二級緩存 -> 一級緩存 -> 資料庫。

MyBatis 是預設關閉二級緩存的,因為對于增删改操作頻繁的話,那麼二級緩存形同虛設,每次都會被清空緩存。

Mybatis一級緩存與二級緩存的差別

1)一級緩存 Mybatis的一級緩存是指SQLSession,一級緩存的作用域是SQlSession, Myabits預設開啟一級緩存。