使用IBatis作數據緩存

使用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(),這樣就刷新了所有的緩存模型而不是某一個.

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