项目完结,整理一些技术方面的相关收获。
已经记不得EhCacheController这个实现类最早来自于那里了,总之稍加修改后非常有效果,大家就这么用了,感谢最初开源的那位兄弟。这里,主要是做个记录,为以后类似扩展(譬如Memcached)做个准备。
iBatis提供CacheController接口,用于实现第三方缓存架构的扩展。
这里以iBatis 2.3.0,EhCache 1.2.3版本为基础,构建iBatis+EhCache实现。
EhCacheController类:
package com.ibatis.sqlmap.engine.cache.ehcache; import java.net.URL; import java.util.Properties; import net.sf.ehcache.Cache; import net.sf.ehcache.CacheManager; import net.sf.ehcache.Element; import com.ibatis.sqlmap.engine.cache.CacheController; import com.ibatis.sqlmap.engine.cache.CacheModel; /** * EhCache Implementation of the * {@link com.ibatis.sqlmap.engine.cache.CacheController} interface to be able * to use EhCache as a cache implementation in iBatis. You can configure your * cache model as follows, by example, in your sqlMapping files: * * <pre> * <code> * <cacheModel id="myCache" readOnly="true" serialize="false" * type="com.ibatis.sqlmap.engine.cache.EhCacheController" > * <property name="configLocation" * value="/path-to-ehcache.xml"/> * </cacheModel> </code> * </pre> * * Alternatively, you can use a type alias in your type attribute and defining * the class with a <code><typeAlias></code> declaration: * * <pre> * <code> * <sqlMapConfig> * <typeAlias alias="EHCACHE" * type="com.ibatis.sqlmap.engine.cache.ehcache.EhCacheController" /> * </sqlMapConfig> * </code> * </pre> * */ public class EhCacheController implements CacheController { /** * The EhCache CacheManager. */ private CacheManager cacheManager; public static final String CONFIG_LOCATION = "configLocation"; /** * Default Configure Location */ public static final String DEFAULT_CONFIG_LOCATION = "/ehcache.xml"; /** * Flush a cache model. * * @param cacheModel * - the model to flush. */ public void flush(CacheModel cacheModel) { getCache(cacheModel).removeAll(); } /** * Get an object from a cache model. * * @param cacheModel * - the model. * @param key * - the key to the object. * @return the object if in the cache, or null(?). */ public Object getObject(CacheModel cacheModel, Object key) { Object result = null; Element element = getCache(cacheModel).get(key); if (element != null) { result = element.getObjectValue(); } return result; } /** * Put an object into a cache model. * * @param cacheModel * - the model to add the object to. * @param key * - the key to the object. * @param object * - the object to add. */ public void putObject(CacheModel cacheModel, Object key, Object object) { getCache(cacheModel).put(new Element(key, object)); } /** * Remove an object from a cache model. * * @param cacheModel * - the model to remove the object from. * @param key * - the key to the object. * @return the removed object(?). */ public Object removeObject(CacheModel cacheModel, Object key) { Object result = this.getObject(cacheModel, key); getCache(cacheModel).remove(key); return result; } /** * Gets an EH Cache based on an iBatis cache Model. * * @param cacheModel * - the cache model. * @return the EH Cache. */ private Cache getCache(CacheModel cacheModel) { String cacheName = cacheModel.getId(); Cache cache = cacheManager.getCache(cacheName); return cache; } /** * Shut down the EH Cache CacheManager. */ public void finalize() { if (cacheManager != null) { cacheManager.shutdown(); } } /** * Configure a cache controller. Initialize the EH Cache Manager as a * singleton. * * @param props * - the properties object continaing configuration information. */ @Override public void configure(Properties props) { String configLocation = props.getProperty(CONFIG_LOCATION); // if can not found ehcache.xml from configLocaion, // use default configure file. if (configLocation == null) { configLocation = DEFAULT_CONFIG_LOCATION; } URL url = getClass().getResource(configLocation); cacheManager = CacheManager.create(url); } }
这里默认在根目录下获取ehcache.xml文件,可以通过cacheModel配置进行修改。
在SqlMapConfig.xml文件中配置一个别名,作为全局变量,供其余SqlMap使用
<typeAlias alias="EHCACHE" type="com.ibatis.sqlmap.engine.cache.ehcache.EhCacheController" />
顺便提一句,要使用缓存注意SqlMapConfig.xml文件中settings节点配置cacheModelsEnabled为true!
<settings cacheModelsEnabled="true" useStatementNamespaces="true" ... />
如果要变更ehcache.xml文件路径为/config/ehcache.xml,可以在上述节点中下入如下代码:
<property name="configLocation" value="/config/ehcache.xml" />
然后,就可以通过ehcache.xml控制ehcache缓存了!
举例说明iBatis SqlMap & ehcahce.xml,以免有些兄弟混淆!
以Account类为示例,在SqlMap中的配置为:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd"> <sqlMap namespace="Account"> <cacheModel id="cache" type="EHCACHE"> <flushInterval hours="1" /> <!-- flush操作,需要指明 Namespace --> <flushOnExecute statement="Account.create" /> </cacheModel> <typeAlias alias="account" type="org.zlex.acl.Account" /> <resultMap id="accountMap" class="account"> <result property="accountId" column="accountId" /> <result property="accountName" column="accountName" /> <result property="mail" column="mail" /> <result property="realName" column="realName" /> <result property="status" column="status" /> <result property="lastLoginTime" column="lastLoginTime" /> </resultMap> <select id="readByAccountName" parameterClass="string" resultMap="accountMap" cacheModel="cache"> <![CDATA[ SELECT accountId, accountName, mail, realName, status, lastLoginTime FROM acl_account WHERE accountName = #accountName# ]]> </select> <insert id="create" parameterClass="account"> <![CDATA[ INSERT INTO acl_account( accountName, mail, realName, status, lastLoginTime ) VALUES ( #accountName#, #mail#, #realName#, #status#, #lastLoginTime# ) ]]> <selectKey resultClass="long" keyProperty="accountId"> <![CDATA[select LAST_INSERT_ID() as id ]]> </selectKey> </insert> </sqlMap>
注意:
引用
<select id="readByAccountName" parameterClass="string" resultMap="accountMap" cacheModel="cache">
这里的cacheModel="cache",对应的在ehcache.xml中就应该是:
<cache name="Account.cache" maxElementsInMemory="10000" eternal="false" maxElementsOnDisk="1000" overflowToDisk="true" timeToIdleSeconds="300" />
因为,我使用了useStatementNamespaces="true"
时间: 2024-11-10 17:14:32