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使用二級緩存。該設置通常用於每次查詢都需要最新的數據情況。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章