Parameter Maps and Inline Parameters
<parameterMap id="parameterMapName" [class="Author"]>
<parameter property ="propertyName" [jdbcType="VARCHAR"] [javaType="string"]
[nullValue="NUMERIC"] [null="-9999999"]/>
<parameter …… />
<parameter …… />
</parameterMap>
括號[]中是可選的屬性。parameterMap 元素的id 屬性作爲唯一標識,在同一個SQL Map XML 文件中不能重名。一個parameterMap 可包含任意多的property 元素。
property屬性是指傳入mapped statement中的JavaBean參數對象的屬性名。這個屬性名可以使用多次,這要看在這個statement中,這個屬性名要出現多少次。例如:
<parameterMap id="authorParameter3" class="Author">
<parameter property="name" jdbcType="VARCHAR" javaType="java.lang.String" mode="INOUT"/>
<parameter property="name" jdbcType="VARCHAR" javaType="java.lang.String" mode="INOUT"/>
</parameterMap>
<update id="updateAuthor2" parameterMap="authorParameter2">
UPDATE author set auth_name=? WHERE auth_name = ?
</update>
但是如果使用這樣的方法的話,調用代碼應該是:
Author author = new Author();
author.setName("作者三");
sqlMapClient.update("updateAuthor2", paraMap);
那麼它其實執行的是:
UPDATE author set auth_name='作者三' WHERE auth_name = '作者三'
這樣的話,就根本沒有了意義,因爲,你只能傳進一個Author對象,而這個Author對象的name屬性值將會被用在整個Sql語句中,而一般的情況下是不應該相同的,也就是說,我們的本意可能是想:
UPDATE author set auth_name='作者N' WHERE auth_name = '作者三'
方法倒是有,不過我覺得不太好。
<parameterMap id="authorParameter2" class="java.util.HashMap">
<parameter property="name1" jdbcType="VARCHAR" javaType="java.lang.String" mode="INOUT"/>
<parameter property="name2" jdbcType="VARCHAR" javaType="java.lang.String" mode="INOUT"/>
</parameterMap>
<update id="updateAuthor2" parameterMap="authorParameter2">
UPDATE author set auth_name=? WHERE auth_name = ?
</update>
調用代碼爲:
HashMap paraMap = new HashMap();
paraMap.put("name1", "作者N");
paraMap.put("name2", "作者三");
sqlMapClient.update("updateAuthor2", paraMap);
如果你想到更好的方法解決這個問題的話,請不吝賜教。
jdbcType用於指明數據庫的字段類型。如果不說明字段類型的話,一些JDBC驅動程序就無法確定要操作的字段類型。例如:PreparedStatement.setNull(int parameterIndex, int sqlType)方法,要求指定數據類型。如果不指定數據類型,某些Driver 可能指定爲Types.Other 或Types.Null。但是,不能保證所有的Driver 都表現一致。對於這種情況,SQL Map API 允許使用parameterMap 元素的jdbcType 屬性指定數據類型。
正常情況下,只有當字段可以爲NULL或日期時間類型時才需要type 屬性。因爲Java 只有一個Date 類型(java.util.Date),而大多數SQL 數據庫有多個-通常至少有3 種。因此,需要指定字段類型是DATE 還是DATETIME。
Type 屬性可以是JDBC Types 類中定義的任意參數的字符串值。雖然如此,還是有某些類型不支持(即BLOB)。
注意!大多數JDBC Driver 只有在字段可以爲NULL 時需要指定type 屬性。因此,對於這些Driver,只是在字段可以爲NULL 時才需要指定type 屬性。
注意!當使用Oracle Driver 時,如果沒有給可以爲NULL 的字段指定type 屬性,當試圖給這些字段賦值NULL 時,會出現"Invalid column。 type"錯誤。
三、javaType
javaType用於指明作爲參數傳遞的java bean的屬性的類型。通常情況下,這可以通過反射機制從java bean中獲取類型,但是一些特定的映射,比如說MAP和XML的映射就無法將類型信息傳遞給框架了。如果java type沒有設置而且框架無法獲知類型的話,那麼這個類型會被指定爲Object。
屬性 nullValue的值可以是對於property 類型來說合法的任意值,用於指定NULL 的替換值。就是說,當Java Bean的屬性值等於指定值時,相應的字段將賦值NULL。這個特性允許在應用中給不支持null的數據類型(即int,double,float等)賦值null。當這些數據類型的屬性值匹配nullValue值(即匹配-9999)時,NULL 將代替nullValue 值寫入數據庫。
例如:
<parameterMap id="authorParameter" class="Author">
<parameter property="name" jdbcType="VARCHAR" javaType="java.lang.String" nullValue="NO_ENTRY" mode="INOUT"/>
<parameter property="age" jdbcType="INTEGER" javaType="java.lang.Integer" nullValue="-999" mode="INOUT"/>
<parameter property="telephone" jdbcType="VARCHAR" javaType="java.lang.String" nullValue="NO_ENTRY" mode="INOUT"/>
<parameter property="address" jdbcType="VARCHAR" javaType="java.lang.String" nullValue="NO_ENTRY" mode="INOUT"/>
</parameterMap>
<insert id="insertAuthor1" parameterMap="authorParameter">
INSERT INTO author (auth_name,auth_age,auth_tel,auth_address) VALUES (?,?,?,?)
</insert>
您可以在另一個SQL Map XML 文件中引用parameterMap。例如,要在另一個文件中引用上面的parameterMap,可以使用名稱"Product.insert-product-param"。
使用Inline Parameter Maps,可以把Java Bean 的屬性名稱嵌在mapped-statement 的定義中(即直接寫在SQL 語句中)。
例如:
<insert id="insertAuthor1" parameterClass="Author">
INSERT INTO author (auth_name,auth_age,auth_tel,auth_address) VALUES (#name#,#age#,#telephone#,#address#)
</insert>
這樣,在你的Author類中,要有name,age,telephone,address的屬性以及相應的get和set方法,這樣做可以避免使用另外定義parameterMap的麻煩。
你也可以在內嵌參數中指定數據類型和nullValue,例如:
<insert id="insertAuthor1" parameterClass="Author">
INSERT INTO author (auth_name,auth_age,auth_tel,auth_address) VALUES (#name:VARCHAR:NO_ENTRY#,#age:INTEGER:-999#,#telephone:VARCHAR:NO_ENTRY#,#address:VARCHAR:NO_ENTRY#)
</insert>
注意!在內嵌參數中,要指定NULL 的替代值,必須要先指定數據類型。
注意!如需要在查詢時也使用NULL 替代值,必須同時在resultMap 中定義。
注意!如果您需要指定很多的數據類型和NULL 替代值,可以使用外部的parameterMap元素,這樣會使代碼更清晰。
在SQL Map 架構中,Result Map 是極其重要的組件。在執行查詢Mapped Statement 時,resultMap 負責將結果集的列值映射成Java Bean 的屬性值。resultMap 的結構如下:
<resultMap id="resultMapName" class="some.domain.Class" [extends="parent-resultMap"]>
<result property="propertyName" column="COLUMN_NAME"
[columnIndex="1"] [javaType="int"] [jdbcType="NUMERIC"]
[nullValue="-999999"] [select="someOtherStatement"]
/>
<result ……/>
<result ……/>
<result ……/>
</resultMap>
括號[]中是可選的屬性resultMap 也有class 屬性,是Java 類的全限定名(即包括包的名稱)或該類的別名。該Java 類初始化並根據定義填充數據。
Extends 是可選的屬性,可以設定成以爲基礎的另外一個resultMap 的名字。和在Java 中繼承一個類相似,父resultMap 的屬性將作爲子resultMap 的一部分。父resultMap 的屬性總是加到子resultMap 屬性的前面,並且父resultMap 必須要在子resultMap 之前定義。父resultMap 和子resultMap 的class 屬性不一定要一致,它們可以沒有任何關係。
resultMap 可以包括任意多的property 映射,將查詢結果集的列值映射成Java Bean 的屬性。屬性的映射按它們在resultMap中定義的順序進行。屬性class 必須符合Java Bean 規範,每一屬性都必須擁有get/set 方法。
注意!ResultSet 的列值按它們在resultMap 中定義的順序讀取。
property屬性是指從mapped statement中返回的JavaBean對象的屬性名。這個屬性名也可以使用多次。
column屬性值是ResultSet中的列名字,即字段名,取得的這個字段的值將賦給property所指的bean屬性。
可選屬性,用於改善性能。屬性columnIndex 的值是ResultSet 中用於賦值Java Bean屬性的字段次序號。在99%的應用中,不太可能需要犧牲可讀性來換取性能。使用columnIndex,某些JDBC Driver可以大幅提高性能,某些則沒有任何效果。
同ParameterMap中的jdbcType
同ParameterMap中的javaType
屬性nullValue指定數據庫中NULL的替代值。因此,如果從ResultSet中讀出NULL值,JavaBean屬性將被賦值爲屬性nullValue指定的替代值。
如果數據庫中存在NULLABLE 屬性的字段,但您想在你的應用程序中用指定的常量代替NULL,您可以這樣做:
<resultMap id="get-product-result" class="Author">
<result property="id" column="auth_id"/>
<result property="age" column="auth_age"/>
<result property="name" column="auth_name" nullValue="you have no name"/>
</resultMap>
在上例中,如果取得的記錄中auth_name字段的值爲NULL,那麼在賦給java bean的時候,name屬性將被賦爲"you have no name"。
如果在一個類與另一個類之間是關聯關係的話,那麼當你用JDBC取得記錄的時候,這個關聯關係是如何實現的呢?例如這樣的關係:一個作者可能會有多個文章發表,那麼作者與文章之間就是很強的關聯關係,而且是一對多的關係,在Author的Bean中是這樣寫的:
public class Author
{
private int id;
.....
private List articleList;
public int getId()
{
return id;
}
public void setId(int id)
{
this.id=id;
}
... ...
public List getArticleList()
{
return articleList;
}
public void setArticleList(List articleList)
{
this.articleList=articleList;
}
}
當你執行一條sql語句從數據表author中取出相應的數據的時候,在上面的java bean中,articleList如何賦值呢?這時候,就需要使用select屬性。
我們先假設在author和article之間使用1:1的關係,雖然在真實世界中是不正確的,我們只是做個例子,那麼Author和article的bean代碼如下:
public class Author
{
private int id;
private int age;
private String name;
private String address;
private String telephone;
private Article article;
public int getId()
{
return id;
}
public void setId(int id)
{
this.id=id;
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age=age;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name=name;
}
public String getAddress()
{
return address;
}
public void setAddress(String address)
{
this.address=address;
}
public String getTelephone()
{
return telephone;
}
public void setTelephone(String telephone)
{
this.telephone=telephone;
}
public Article getArticle()
{
return this.article;
}
public void setArticle(Article article)
{
this.article=article;
}
}
public class Article
{
private int id;
private String title;
private Date createtime;
private int author;
public int getId()
{
return id;
}
public void setId(int id)
{
this.id=id;
}
public String getTitle()
{
return title;
}
public void setTitle(String title)
{
this.title=title;
}
public Date getCreatetime()
{
return createtime;
}
public void setCreatetime(Date createtime)
{
this.createtime=createtime;
}
public int getAuthor()
{
return author;
}
public void setAuthor(int author)
{
this.author=author;
}
}
在author.xml的配置如下:
<resultMap id="linkResultMap1" class="Author">
<result property="id" column="auth_id"/>
<result property="age" column="auth_age"/>
<result property="name" column="auth_name"/>
<result property="telephone" column="auth_tel"/>
<result property="address" column="auth_address"/>
<result property="article" column="auth_id" select="getLinkArticle1"/>
</resultMap>
<select id="getAuthor5" resultMap="linkResultMap1" parameterClass="int">
SELECT * FROM author WHERE auth_id = #id#
</select>
<select id="getLinkArticle1" resultClass="com.ibatis.beans.Article" parameterClass="int">
SELECT art_id as id,art_title as title,art_createtime as createtime,art_author as author FROM article WHERE art_id = #id#
</select>
調用代碼如下:
Author author = (Author)sqlMapClient.queryForObject("getAuthor5", new Integer(1));
System.out.println(author.getName()+"'s article is :"+author.getArticle().getTitle());
你可以看到,對於Author類中的article屬性,IBatis是將取得的記錄的auth_id字段值作爲參數傳入到id="getLinkArticle1"的語句中,並將取得的結果封裝成Article對象,並賦給Author的article屬性。上面的調用代碼實際執行的兩條sql語句是:
SELECT * FROM author WHERE auth_id = 1
SELECT art_id as id,art_title as title,art_createtime as createtime,art_author as author FROM article WHERE art_id = 1
在第二條語句中,將取得的記錄封裝成Article對象,並賦給Author的article屬性,所以,你可以直接使用author.getArticle().getTitle()獲得文章的標題。
上面的方法顯示瞭如何實現1:1的關聯關係,但是上面的方法並不好,原因是可能會執行很多次查詢!
(1)避免 N+1 Selects (1:1)
如果上面的配置如下:
<resultMap id="linkResultMap1" class="Author">
<result property="id" column="auth_id"/>
<result property="age" column="auth_age"/>
<result property="name" column="auth_name"/>
<result property="telephone" column="auth_tel"/>
<result property="address" column="auth_address"/>
<result property="article" column="auth_id" select="getLinkArticle1"/>
</resultMap>
<select id="getAuthor5" resultMap="linkResultMap1" parameterClass="int">
SELECT * FROM author WHERE auth_id > #id#
</select>
<select id="getLinkArticle1" resultClass="com.ibatis.beans.Article" parameterClass="int">
SELECT art_id as id,art_title as title,art_createtime as createtime,art_author as author FROM article WHERE art_id = #id#
</select>
調用代碼如下:
Author author = (Author)sqlMapClient.queryForList("getAuthor5", new Integer(1));
如果SELECT * FROM author WHERE auth_id > 1的記錄有N條,那麼將對id="getLinkArticle1"的語句執行N次查詢,這樣所有的查詢總數將爲N+1次,執行效率會很低。
這時,可以使用下面的聯合查詢的方法來解決:
<resultMap id="linkResultMap2" class="Author">
<result property="id" column="auth_id"/>
<result property="age" column="auth_age"/>
<result property="name" column="auth_name"/>
<result property="telephone" column="auth_tel"/>
<result property="address" column="auth_address"/>
<result property="article.title" column="art_title"/>
</resultMap>
<select id="getAuthor6" resultMap="linkResultMap2" parameterClass="int">
<![CDATA[ SELECT a.auth_id,a.auth_age,a.auth_name,a.auth_tel,a.auth_address,b.art_title FROM author a,article b WHERE a.auth_id > #id# and a.auth_id = b.art_id]]>
</select>
調用代碼爲:
Author author = (Author)sqlMapClient.queryForList("getAuthor6", new Integer(1));
這樣只用一條Sql語句就可以解決。
下面我們討論1:M的關係,一個author可能有多個article,所以,author與article之間是一對多的關係。那麼我們在Author類中加入如下代碼(在省略號間的是要加入的代碼):
public class Author
{
... ...
private List articleList;
public List getArticleList()
{
return articleList;
}
public void setArticleList(List articleList)
{
this.articleList=articleList;
}
... ...
}
配置如下:
<resultMap id="linkResultMap3" class="Author">
<result property="id" column="auth_id"/>
<result property="age" column="auth_age"/>
<result property="name" column="auth_name"/>
<result property="telephone" column="auth_tel"/>
<result property="address" column="auth_address"/>
<result property="articleList" column="auth_id" select="getLinkArticle3"/>
</resultMap>
<select id="getAuthor7" resultMap="linkResultMap3" parameterClass="int">
SELECT * FROM author WHERE auth_id = #id#
</select>
<select id="getLinkArticle3" resultClass="com.ibatis.beans.Article" parameterClass="int">
SELECT art_id as id,art_title as title,art_createtime as createtime,art_author as author FROM article WHERE art_author = #id#
</select>
調用代碼爲:
Author author = (Author)sqlMapClient.queryForObject("getAuthor7", new Integer(1));
System.out.println(author.getName()+"的文章有:");
for(int i=0;i<author.getArticleList().size();i++)
{
int num=i+1;
Article art = (Article)author.getArticleList().get(i);
System.out.println(num+". "+art.getTitle());
}
從上面的實現可以看出,你只需要在bean中加入一個java.util.List(或java.util.Collection)類型的articleList來表示所有的文章列表即可,調用部分沒有什麼變化,IBaits會自動從Article中取得的記錄封裝成Article對象並加入到一個List對象中,然後將這個List對象賦值給Author類的articleList屬性。
(1)避免 N+1 Selects (1:M and M:N)
1:M和M:N的情況與1:1的情況相似,也會出現N+1 Selects 的情況,但是到目前位置,還沒有其他的方法來解決這個問題,希望在不久的將來能夠解決。
你可能已經注意到了,上面的例子中,在resultMap中只指明瞭一個column屬性用於id=”getLinkArticle”的statement關聯。其實,Ibatis允許你指明多個column屬性與id=”getLinkArticle”的statement關聯,語法很簡單, {param1=column1, param2=column2, …, paramN=columnN}。下面是一個例子:
<resultMap id="linkResultMap4" class="Author">
<result property="id" column="auth_id"/>
<result property="age" column="auth_age"/>
<result property="name" column="auth_name"/>
<result property="telephone" column="auth_tel"/>
<result property="address" column="auth_address"/>
<result property="articleList" column="{id=auth_id,address=auth_address}" select="getLinkArticle4"/>
</resultMap>
<select id="getAuthor8" resultMap="linkResultMap4" parameterClass="int">
SELECT * FROM author WHERE auth_id = #id#
</select>
<select id="getLinkArticle4" resultClass="com.ibatis.beans.Article" parameterClass="int">
SELECT art_id as id,art_title as title,art_createtime as createtime,art_author as author FROM article WHERE art_author = #id# and art_publish_add=#address#
</select>
你也可以只寫字段的名稱,只要按照所關聯的statement中所對應的字段順序即可,象這樣:
{auth_id,auth_address}
上面的這個例子我在Mysql的環境中運行沒有通過,報出的錯誤是:Column'{auth_id,auth_address}' not found.
這個錯誤是與JDBC驅動無關的,而是在做XML解析的時候發生的錯誤,不知道是什麼原因,如果您有這樣的成功經歷的話,希望能共同分享,我的Email是:
[email protected]
注意:有些JDBC驅動不支持同時打開多個ResultSets(單個連接)。所以說,這樣的驅動不能完成複雜對象的映射,因爲JDBC驅動需要多個ResultSets的連接,這時候,只能使用一個關聯查詢解決問題。
如果你使用Microsoft SQL Server 2000 的JDBC驅動的話,你需要在配置url的時候,在url後加上SelectMethod=Cursor。
Java Type |
JavaBean/Map
Property Mapping |
Result Class /
Parameter Class*** |
Type Alias** |
boolean |
YES |
NO |
boolean |
java.lang.Boolean |
YES |
YES |
boolean |
byte |
YES |
NO |
byte |
java.lang.Byte |
YES |
YES |
byte |
short |
YES |
NO |
short |
java.lang.Short |
YES |
YES |
short |
int |
YES |
NO |
Int/ Integer |
java.lang.Integer |
YES |
YES |
Int/ Integer |
long |
YES |
NO |
long |
java.lang.Long |
YES |
YES |
long |
float |
YES |
NO |
float |
java.lang.Float |
YES |
YES |
float |
double |
YES |
NO |
double |
java.lang.Double |
YES |
YES |
double |
java.lang.String |
YES |
YES |
string |
java.util.Date |
YES |
YES |
date |
java.math.BigDecimal |
YES |
YES |
decimal |
* java.sql.Date |
YES |
YES |
N/A |
* java.sql.Time |
YES |
YES |
N/A |
* java.sql.Timestamp |
YES |
YES |
N/A |
<cacheModel id="product-cache" type ="LRU" readOnly=”true” serialize=”false”>
<flushInterval hours="24"/>
<flushOnExecute statement="insertProduct"/>
<flushOnExecute statement="updateProduct"/>
<flushOnExecute statement="deleteProduct"/>
<property name=”cache-size” value=”1000” />
</cacheModel>
上面的cache model 創建了一個名爲“product-cache”的緩存,使用“最近最少使用”(LRU)實現,每24小時,緩衝區將刷新一次,而且在執行insertProduct、updateProduct和deleteProduct的statement時,緩衝區也將刷新,設定的時間可以設定爲hours, minutes, seconds或 milliseconds。一些Cache的實現需要附加的屬性,比如說上例中的cache-size
屬性,cache的大小指明瞭可以存放在cache中的實體的個數。type屬性的名稱要麼是全限定的類名,要麼是緩存實現的別名。Cache Model 使用插件的形式來支持不同的緩存算法。它的實現在cache-model 元素的type屬性中指定(如上所示)。
(一)Read-Only 與 Read/Write
Ibatis支持只讀和可讀寫的Cache,只讀的Cache可以在所有的用戶間共享,所以它可以提供更大的操作空間。但是從只讀緩衝中讀取的對象不能夠被修改。如果你要對你取得的對象進行修改的話,那麼你只能用可讀寫的緩衝。readOnly=”true”爲只讀緩衝;readOnly=”false”爲可讀寫緩衝。
(二)Serializable Read/Write Caches
要使用Serializable Read/Write Caches,設置readOnly=”false”,serialize=”true”。默認情況下,採用的是readOnly=” true”,serialize=”false”。
目前包括以下的4 個緩衝類型實現:
1. “MEMORY” (com.ibatis.db.sqlmap.cache.memory.MemoryCacheController)
MEMORY cache 實現使用reference 類型來管理cache 的行爲。垃圾收集器可以根據reference 類型判斷是否要回收cache 中的數據。MEMORY 實現適用於沒有統一的對象重用模式的應用,或內存不足的應用。
MEMORY 實現可以這樣配置:
<cache-model name="product-cache" implementation ="MEMORY">
<flush-interval hours="24"/>
<flush-on-execute statement="insertProduct"/>
<flush-on-execute statement="updateProduct"/>
<flush-on-execute statement="deleteProduct"/>
<cache-property name=”reference-type” value=”WEAK” />
</cache-model>
MEMORY cache 實現只認識一個<cache-property>元素。這個名爲“reference-type”屬性的值必須是STRONG,SOFT 和WEAK 三者其一。這三個值分別對應於JVM 不同的內存reference 類型。
(1) WEAK(缺省)
大多數情況下,WEAK類型是最佳選擇。如果不指定類型,缺省類型就是WEAK。它能大大提高常用查詢的性能。但是對於當前不被使用的查詢結果數據,將被清除以釋放內存用來分配其他對象。
(2) SOFT
在查詢結果對象數據不被使用,同時需要內存分配其他對象的情況下,SOFT類型將減少內存不足的可能性。然而,這不是最具侵入性的reference類型,結果數據依然可能被清除。
(3) STRONG
確保查詢結果數據一直保留在內存中,除非Cache被刷新(例如,到了刷新的時間或執行了更新數據的操作)。
對於下面的情況,這是理想的選擇:
1” 結果內容數據很少
2” 完全靜態的數據
3” 頻繁使用的數據
優點是對於這類查詢性能非常好。缺點是,如果需要分配其他對象,內存無法釋放(可能是更重要的數據對象)。
2. “LRU” (com.ibatis.db.sqlmap.cache.lru.LruCacheController)
LRU Cache 實現用“最近最少使用”原則來確定如何從Cache 中清除對象。當Cache溢出時,最近最少使用的對象將被從Cache 中清除。
<cache-model name="product-cache" implementation ="LRU">
<flush-interval hours="24"/>
<flush-on-execute statement="insertProduct"/>
<flush-on-execute statement="updateProduct"/>
<flush-on-execute statement="deleteProduct"/>
<cache-property name=”cache-size” value=”1000” />
</cache-model>
值得注意的是,這裏指的對象可以是任意的,從單一的String 對象到Java Bean 的ArrayList 對象都可以。因此,不要Cache 太多的對象,以免內存不足。
3. “FIFO” (com.ibatis.db.sqlmap.cache.fifo.FifoCacheController)
FIFO Cache 實現用“先進先出”原則來確定如何從Cache 中清除對象。對於短時間內持續引用特定的查詢而後很可能不再使用的情況,FIFO Cache 是很好的選擇。
<cache-model name="product-cache" implementation ="FIFO">
<flush-interval hours="24"/>
<flush-on-execute statement="insertProduct"/>
<flush-on-execute statement="updateProduct"/>
<flush-on-execute statement="deleteProduct"/>
<cache-property name=”cache-size” value=”1000” />
</cache-model>
值得注意的是,這裏指的對象可以是任意的,從單一的String 對象到Java Bean 的ArrayList 對象都可以。因此,不要Cache 太多的對象,以免內存不足。
4. “OSCACHE” (com.ibatis.db.sqlmap.cache.oscache.OSCacheController)
OSCACHE Cache 實現是OSCache2.0 緩存引擎的一個Plugin。它具有高度的可配置性,分佈式,高度的靈活性。
<cache-model name="product-cache" implementation ="OSCACHE">
<flush-interval hours="24"/>
<flush-on-execute statement="insertProduct"/>
<flush-on-execute statement="updateProduct"/>
<flush-on-execute statement="deleteProduct"/>
</cache-model>
OSCACHE 實現不使用cache-property 元素。而是在類路徑的根路徑中使用標準的oscache.properties 文件進行配置。在oscache.properties 文件中,您可以配置Cache 的算法(和上面討論的算法很類似),Cache 的大小,持久化方法(內存,文件等)和集羣方法。
要獲得更詳細的信息,請參考OSCache 文檔。OSCache 及其文檔可以從OpenSymphony網站上獲取:http://www.opensymphony.com/oscache/