使用IBatis作數據緩存
1.SqlMapConfig.xml中
<settings
cacheModelsEnabled="true" //設置爲true
enhancementEnabled="true"
lazyLoadingEnabled="true"
.............
/>
2.cacheModel cacheModel的屬性值等於指定的cacheModel元素的name屬性值。屬性cacheModel定義查詢mapped statement的緩存。每一個查詢mapped statement可以使用不同或相同的cacheModel。詳細討論見後面的章節,以下只給出個例子。
<cacheModel id="product-cache" imlementation="LRU">
<flushInterval hours="24"/>
<flushOnExecute statement="insertProduct"/>
<flushOnExecute statement="updateProduct"/>
<flushOnExecute statement="deleteProduct"/>
<property name=”size” value=”1000” />
</cacheModel>
<statement id=”getProductList” parameterClass=”int” cacheModel=”product-cache”> select * from PRODUCT where PRD_CAT_ID = #value#
</statement>
上面例子中,“getProductList”的緩存使用WEAK引用類型,每24小時刷新一次,或當更新的操作發生時刷新。
關於ibatis補充說明
<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)通常能獲得較好的效果。
※《ibatis開發指南》有關於上面幾種緩存類型的詳細說明。
<cacheModel type="OSCACHE" id="cache">
<flushInterval hours="24"/>
<flushOnExecute statement="WapIndex.delete"/>
<flushOnExecute statement="WapIndex.update"/>
<property value="100" name="size"/>
</cacheModel>
2007-7-9 11:45:42 IBatis中的強制刷新緩存 目前我們採用IBatis作ORM, 所以我們直接使用了IBatis 自帶的緩存解決方案。當然你也可以定製,我在我的一篇文章可複用、擴展的緩存設計方案也談到了如何定製 ,個人認爲如果不是非常複雜的需求,完全可以藉助ORM自帶的方案.你會發現非常非常簡單.
下面我們進入實戰:
step1)寫ibatis的相關配置
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN"
"http://www.ibatis.com/dtd/sql-map-2.dtd">
<sqlMap namespace="specialtopic">
............
<cacheModel id="getTopVideoListByColumn1-cache" type ="OSCACHE" >
<flushInterval seconds="60"/>
</cacheModel>
............
<statement id="getTopVideoListByColumn1" resultMap="top-Video-column1" cacheModel="getTopVideoListByColumn1-cache">
select v.videoId,v.title,v.timeSpan,tu.loginName,vr.viewedCount
from top_baby_video tbv
inner join video v on tbv.videoId=v.videoId
inner join video_report vr on v.videoId=vr.videoId
inner join tvUser tu on v.tvUserId=tu.tvUserId
</statement>
</sqlMap>
顯而易見上面的cacheModel是緩存策略, 只需加在statement段的屬性中即可
step2)寫dao方法
public List getTopVideoListByColumn1 ()...{
List list = this.getSqlMapClientTemplate().queryForList("getTopVideoListByColumn1",
null);
return list;
}
就是這麼簡單,從客戶端的角度看,緩存是透明的.你可以從配置文件修改你的緩存策略,不會對你的java代碼造成任何影響.
強制刷新緩存的功能,如何實現?馬上進入實戰:
我們通過一個jsp搞定<%@ page import="xxx.common.utils.SpringBeanProxy"%>
<%@ page import="com.ibatis.sqlmap.client.SqlMapClient"%>
<%
String cacheModelId = request.getParameter("cacheModelId");
SqlMapClient client = (SqlMapClient) SpringBeanProxy
.getBean("sqlMapClient");
client.flushDataCache(cacheModelId);
%>
ok!
首先我們獲取需要刷新緩存的id,然後從spring工廠中取出SqlMapClient ,然後利用SqlMapClient刷新緩存
其實你也可以調用client.flushDataCache(),這樣就刷新了所有的緩存模型而不是某一個.