MyBatis的查詢緩存管理
1. 查詢緩存工作原理
查詢語句 <--> 緩存 <--> DB
(解讀:當執行到查詢語句時,會首先到緩存中查找,若緩存中有,則直接返回給查詢語句,
若沒有,則再到DB中查找,查找到的內容首先返回給緩存,在返還到查詢語句)
2.查詢緩存中的緩存內容
MyBatis查詢緩存中存放的是"查詢結果"
3.緩存分類
MyBatis查詢緩存根據作用範圍與生命週期的不同,可以分爲兩類:
(1)一級緩存,也稱爲SqlSession緩存. 默認是開啓的,無法關閉.
(2)二級緩存,默認是關閉的,若要使用,必須開啓.
二級緩存可以分爲兩類: <1>內置二級緩存 <2>外置第三方緩存產品
MyBatis查詢緩存分類 如下表格:
類別 作用範圍 生命週期
一級緩存 namespace 與SqlSession的生命週期相同
二級緩存 namespace 與整個應用的生命週期相同
詳細講解:
3.1 一級緩存
(1) 一級緩存中存放的不是查詢出的對象本身,而是一個Map.
一級緩存的底層實現是一個Map
* key:hashCode + statement + SQL
* value:查詢結果(2) 增刪改操作會刷新一級緩存(即 清空一級緩存)
3.2 二級緩存
3.2.1 內置二級緩存
(1) 內置二級開啓方式 分兩步:
a. 在映射文件中添加<cache/>標籤
二級緩存是可以設置的(內置配置)(<cache標籤中有如下屬性:>)
size:指二級緩存中可以存放多少個查詢結果(查詢一次爲一個查詢結果),默認值是1024
eviction:逐出策略
flushInterval:刷新緩存的間隔
type屬性:設置二級緩存使用什麼類型,默認是內置二級緩存b. 操作的實體類要實現Serializable接口(序列化接口)
(2) 內置二級緩存使用原則:
a. 不要出現多個namespace操作一張表的情況
b. 對關聯關係不要出現增刪改操作
c. 當查詢操作多於增刪改操作時可以使用二級緩存
3.2.2 外置二級緩存(以EHCache爲例)
(1) EHCache二級查詢緩存 開啓方式 (分兩步)
a. 導入兩個jar包
EHCache核心jar包 : ehcache-core-2.6.8.jar
EHCache與MyBatis整合jar包 : mybatis-ehcache-1.0.3.jar
b. 在映射文件中添加<cache/>標籤並指定type
即: <cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
(2) EHCache二級查詢緩存-- 配置
配置文件在ehcache-core-2.6.8.jar --> ehcache-failsafe.xml中,
使用 : a. 將該文件拷貝到src根目錄下,(需要將ehcache-failsafe.xml改名爲ehcache.xml) 即起到作用.
b. 也可以在映射文件中<cache></cache>標籤中設置,(當在映射文件中設置配置後,以映射文件中的設置爲準,不再以配置文件爲準).
如: <cache type="org.mybatis.caches.ehcache.EhcacheCache">
<property name="maxElementsInMemory" value="1000"/>
<property name="timeToIdleSeconds" value="240"/>
<property name="timeToLiveSeconds" value="240"/>
</cache>解讀配置文件(瞭解):
<defaultCache
maxElementsInMemory="10000" 內存中存放的最多的元素個數,類似於內置二級緩存中的size
eternal="false" 不是永恆的,只有當它是false時,下面的設置纔有用
timeToIdleSeconds="120" 空閒的時間
timeToLiveSeconds="120" 存活的時間
maxElementsOnDisk="10000000" 在硬盤中的存放最多的元素,當內存中達到最大值,會存放在此,存放路徑爲: <diskStore path="java.io.tmpdir"/> ------ java.io.tmpdir是一個系統常量,具體路徑在測試類test03中測試.是一個臨時目錄.
diskExpiryThreadIntervalSeconds="120" 在硬盤的最長時間
memoryStoreEvictionPolicy="LRU"> 內存存儲逐出策略
<persistence strategy="localTempSwap"/> persistence持久化,設置此處纔可以使用存放到硬盤
</defaultCache>
(1) 增刪改操作對二級緩存的影響 (內外置同樣適用)
a. 二級緩存的底層也是一個Map
* key:hashCode + statement + SQL
* value:查詢結果b. 刷新二級緩存實際上執行了什麼?
增刪改操作會刷新(清空)二級緩存,但是刷新二級緩存實際上是將二級緩存中的Entry對象的value指置爲null,並未刪除整個Entry對象,key仍保留.
c. 什麼時候真正執行到DB中的select查詢?
有兩種情況可以到DB中執行真正的待查詢:
<1>Map中根本就不存在要查找的Entry對象,即沒有要查找的key
<2>Map中存在要查找的key,但其value爲nulld. 增刪改操作默認是可以影響二級緩存的,但也可以設置爲不影響
只需在增刪改的Statement中(即寫sql語句的標籤中<映射文件裏>)添加flushCache="false"屬性即可
(2) 二級緩存的關閉 分爲兩類:(內外置同樣適用)
a. 全局性關閉
即 當前應用中所有的查詢均不能使用二級緩存.
方法: 在主配置文件中進行如下設置:
<settings>
<!-- 二級緩存的全局性開關 -->
<setting name="cacheEnabled" value="false"/>
</settings>b.局部性關閉
即 可以指定某一個查詢不使用二級緩存
方法: 在該查詢對應的<select/>標籤中添加 useCache="false" 屬性即可關閉當前的select的二級緩存.但並不影響
其它select語句使用二級緩存.