IBATIS(MyBatis)高速緩存

 一.iBATIS高速緩存介紹
1.1 iBATIS高速緩存只關注如何在持久層對查詢結果進行緩存。

1.2 iBATIS帶來的好處就是通過配置文件來管理高速緩存,幫助避免因手工管理高速緩存結果及其依賴性而造成的大量繁瑣的工作。

1.3 iBATIS高速緩存和傳統O/RM高速緩存的區別
iBATIS的思想是建立SQL語句到對象的映射,而不是建立數據庫表到對象的映射。傳統O/RM工具主要關注數據庫表到對象的映射。傳統的O/RM高速緩存會爲其管理的每個對象維護一個OID[object identification,對象標識],就像數據庫需要管理其表中的每條記錄的唯一性一樣。這意味着,如果兩個不同的結果都返回同一個對象,那麼該對象將只被高速緩存一次。iBATIS不這樣,關注的是SQL語句的執行結果,我們不會根據對象的唯一性來高速緩存它們iBATIS高速緩存的所有結果,而不考慮所標識的對象是否存在於高速緩存中。

二.配置iBATIS緩存
2.1 、cacheModel標籤
cacheModel標籤用來配置iBATIS的高速緩存,cacheModel標籤的屬性包括四個屬性
id[必需]
該值用來指定一個唯一的ID,便於爲需要使用此高速緩存模型所配置的高速緩存的查詢已映射語句使用。
type[必需]
此屬性用於指定高速緩存所配置的高速緩存的類型。其有效值包括MEMORY LRU FIFO OSCACHE,該屬性也可取值爲某個自定義CacheController實現的全限定名。
readOnly[可選]
取值爲true時表示高速緩存將僅僅用作只讀緩存,從只讀高速緩存中讀出的對象的特性值不允許修改。
serialize[可選]
該屬性用於指定在讀取高度緩存內容時是否要進行“深複製”
readOnly、serialize屬性經常聯合起來使用。

2.2 、iBATIS高速緩存模型的類型
2.2.1 MEMORY
MEMORY高速緩存是一種基於引用的高速緩存。MEMORY高速緩存模型對於那些更關注內存的管理策略而不是對象的訪問策略的應用程序而言是完美的。有了STRONG、SOFT、WEAK這三種引用類型,就可以確定哪些結果應該比其他結果保留更長的時間。
2.2.2 LRU
LRU類型的高速緩存模型使用最近最少使用策略來管理高速緩存。該高速緩存的內部機制會在後臺記錄哪些對象最近最少使用,一旦超過高速緩存大小限制就會廢棄它們。大小限制規定了高速緩存中可以存放的對象數目。應避免將那些佔用較大內存的對象放置在此類高速緩存中,否則內存會很快耗盡。
LRU高速緩存非常設用於那些需要根據某些特定對象的訪問頻率來管理的高速緩存的情況。通常這種高速緩存策略試用於那些需要高速緩存用於分頁結果或關鍵詞搜索結果的對象應用程序中。
2.2.3 FIFO
FIFO高速緩存模型採用先進先出的管理策略,是一種基於時間的策略,使用於放置那些初放入時使用頻率高、隨時間流逝訪問頻率就會降低的對象。如:報表、報告股票價格。
2.2.4 OSCACHE
OSCache是個一個廣泛採用的高性能的J2EE緩存框架,OSCache能用於任何Java應用程序的普通的緩存解決方案。OSCache有以下特點:
緩存任何對象,你可以不受限制的緩存部分jsp頁面或HTTP請求,任何java對象都可以緩存。
  擁有全面的API--OSCache API給你全面的程序來控制所有的OSCache特性。
  永久緩存--緩存能隨意的寫入硬盤,因此允許昂貴的創建(expensive-to-create)數據來保持緩存,甚至能讓應用重啓。
  支持集羣--集羣緩存數據能被單個的進行參數配置,不需要修改代碼。
  緩存記錄的過期--你可以有最大限度的控制緩存對象的過期,包括可插入式的刷新策略(如果默認性能不需要時)
2.2.5自定義高速緩存模型
只需要實現com.ibatis.sqlmap.engine.cache.CacheController接口即可,配置時設定type爲全限類名或其別名即可。

2.3 高速緩存的清除
使用flushOnExecute、flushInterval標籤可以定義清空緩存觸發條件
<flushOnExecute> 定義查詢已映射語句,其執行將引起相關高速緩存的清除
<flushInterval> 定義一個時間間隔,高速緩存將以此間隔定期清除
<flushInterval>標籤屬性如下:
hours(可選) 每次清除高速緩存前應該經過的小時數
minutes(可選) 每次清除高速緩存前應該經過的分鐘數
seconds(可選) 每次清除高速緩存前應該經過的秒數
milliseconds(可選) 每次清除高速緩存前應該經過的毫秒數

2.4 設置高速緩存模式實現的特性
由於高速緩存模型只是一些可以插入到iBATIS框架的組件,它甚至允許用戶自己定製,因此必須有一種方式能爲這些組件提供任意的值。<property>標籤就是用來完成此任務的。name :所設定的特性的名稱,value:所設定的特性的值。

2.5 常見問題
2.5.1如何選擇iBATIS高速緩存模型類型
如何選擇一個適合實際應用情況的高速緩存模型類型是一個很負責的問題,需要考慮諸多因素。
需要考慮的因素:
1.當前應用程序是否是數據庫的唯一操作入口
2.讀寫屬性
3.緩存時間間隔
4.失效控制
5.最大保存對象數目

在你的xml配置文件中,每一個 cacheModel 元素,如下

<cacheModel id=oneday_cache type=LRU readOnly=false serialize=true>
<flushInterval hours=24/>
<flushOnExecute statement=updateMyDate/>
<property name=size value=200/>
</cacheModel>



1 屬性readOnly如果不寫,默認是true,這時的緩存效果無疑最好,因爲系統不需要考慮更新操作引起緩存與實際數據不一致的問題,只讀緩存的例子是固化到數據庫中的一些配置參數表。但是,通常我們想緩存的數據是需要增刪改的,這時務必記得要加上 readOnly = false;
2 屬性serialize,如果不寫,默認爲false, 將它設爲true,可以提高整體應用(而不僅僅是每個Session)的性能。 這種緩存爲每一個Session返回緩存對象不同的實例(複本)。因此每一個Session都可以安全修改返回的對象. 注意,此時readOnly必須爲false。
如果你把它設爲 true ,記得檢查兩件事,一件事是緩存中存放的對象(你想查詢的POJO)必須是可序列化的, 即實現Serializable接口。如果你有一個複雜對象屬性,它也必須滿足這個規則,你的整個對象樹必須是可序列化的。
另一件事是關閉sql-map-config中的延遲加載屬性,即lazyload=false,原因是,它使用了動態代理機制, 那個代理對象並不是Serializable的。

緩存類型的最佳適應情形:

MEMORY 沒有統一的對象重用模式的應用,或內存不足的應用。
LRU 在較長的期間內,用戶經常使用某些特定對象。
FIFO 用戶在短時間內持續引用特定的查詢,而後很可能不再使用。

根據個人實踐,內存充足時使用LRU,否則使用MEMORY(WEAK)通常能獲得較好的效果。

發佈了36 篇原創文章 · 獲贊 2 · 訪問量 32萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章