1. 程式人生 > >MyBatis快取機制

MyBatis快取機制

快取機制是為了減輕資料庫壓力,提高資料庫效能。 
Mybatis查詢快取分為一級快取和二級快取,預設開啟一級快取。

  • 一級快取是SqlSession級別的快取,PerpetualCache
  • 二級快取是mapper級別的快取。是多個SqlSession共享的。

一、一級快取SqlSession級別

一級快取是SqlSession級別的快取,在操作資料庫時需要構造SqlSession物件,在物件中有一個HashMap用於儲存快取資料。不同的SqlSession之間的快取資料區域HashMap是互不影響的。

Mybatis快取機是基於id進行快取的,也就是說,Mybatis使用HashMap快取資料時,是使用物件的id

作為key,而物件作為value儲存的。

第一次以id1進行查詢執行了一條select語句,第二次獲取id1的資料,不會再執行select語句。

如果不執行session.commit(),操作沒有提交到資料庫,此時Mybatis不會清空SqlSession快取。

若在第一次查詢id為的資料時執行了一條select語句,接下來執行了一個update,delete,insert into操作,Mybatis為了保證快取中儲存的最新資訊,會清空SqlSession快取。

因一級快取是SqlSession級別的,如果在執行第一次根據id查詢後,執行了close()方法,該方法會關閉SqlSession

快取,第二次根據相同的id查詢,一級快取也就是SqlSession快取是一個新的物件,會再次執行select語句。

在實際的專案開發中,往往會將MybatisSpring整合,SqlSession會交給Spring管理,每查詢結束後,Spring會清空當前的SqlSession釋放資源,也就每次查詢所使用的SqlSession是不相同的,導致Mybatis的一級快取失效。

二、二級快取mapper級別

二級快取是mapper級別的快取,是多個SqlSession使用同一個mappersql語句去操作資料庫,得到的資料會存在二級快取區域。

二級快取也是使用HashMap進行資料儲存的,範圍比一級快取更大,是跨SqlSession

的,多個SqlSession可以共用二級快取。

二級快取是多個SqlSession共享的,其作用域是mapper的同一個namespace。不同的SqlSession兩次執行相同namespace下的sql語句,且向sql中傳遞的引數也相同,即最終執行相同的sql語句,即第一次執行完畢會將從資料庫查詢到的資料寫入快取(記憶體),第二次查詢會從快取中獲取資料,不再去底層資料庫查詢,從而提高查詢效率。

當Mybatis在一級快取中沒有找到與id對應的物件時,就會去二級快取中查詢,如果還沒有,就去資料庫查詢。

Mybatis預設沒有開啟二級快取,需要在setting全域性引數中配置開啟二級快取。開啟配置如下:

<settings>
<!-- 開啟二級快取 -->
<setting name="cacheEnabled" value="true"/>
</settings>

開始當前mappernamespace下的二級快取,xxxMapper.xml

<!-- 建立一個LRU快取,並每隔60秒重新整理,最大儲儲512個物件,返回物件是隻讀 -->
<cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"/>
cache開啟當前mappernamespace下的二級快取。該元素屬性設定如下:
  • flushInterval重新整理間隔,單位毫秒,預設不設定沒有重新整理間隔,在呼叫時重新整理。
  • size快取數目,需要快取的物件數目,預設值是1024。
  • readOnly只讀,可設定為truefalse。預設false,可讀寫,返回的是快取物件的拷貝(通過序列化),會慢些,但安全。

使用二級快取時,與查詢結果對映的Java物件,必須實現java.io.Serializable介面的序列化和反序列化操作。如果存在你的父類,其成員都需要實現序列化介面。

實現序列化介面是為了對快取資料進行序列化和反序列化操作,因為二級快取資料儲存介質多樣,不一定在記憶體,有可能是硬碟或遠端伺服器。

select中設定useCache=false,可以禁用當前select語句的二級快取,即每次查詢都會發出sql查詢,預設是true即開該了二級快取則該sql使用二級快取。該設定通常用於每次查詢都需要最新的資料情況。