Dashboard > iBATIS DataMapper > Home > 3rd Party Contributions > EHCache support for iBatis
EHCache support for iBatis
Added by Chadwick, last edited by Chadwick on Jun 21, 2009  (view change) show comment
Labels: 
(None)


EHCache support for iBatis

The following CacheController implementation and configuration enables you to delegate iBatis caching to EhCache.

First, the class:

package com.ibatis.sqlmap.engine.cache.EhCacheController;
    
    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:
    * <cacheModel id="myCache" type="nl.rabobank.springproject.ibatis.EhCacheController" readOnly="true" serialize="false">
    *   <property name="configFile" value="/path-to-ehcache.xml"/>
    * </cacheModel>
    * Alternatively, you can use a type alias in your type attribute and defining the class with a
    * <TypeAlias> declaration, see iBatis documentation on how to do this.
    */
    public class EhCacheController implements CacheController {
    
    /** The EhCache CacheManager. */
    private CacheManager cacheManager;
    
    /**
    * 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;
    }
    
    /**
    * Configure a cache controller. Initialize the EH Cache Manager as a singleton.
    * @param props - the properties object continaing configuration information.
    */
    public void setProperties(Properties props) {
    URL url = getClass().getResource(props.getProperty("configFile"));
    cacheManager = CacheManager.create(url);
    }
    
    /**
    * 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();
    }
    }
    }

Next, a sample sql Mapping config:

<?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="myNamespace">
    
    
    <!-- Use type aliases to avoid typing the full classname every time. -->
    <typeAlias alias="MyPojo" type="nl.myproject.MyPojo"/>
    <typeAlias alias="MapCacheController" type="com.ibatis.sqlmap.engine.cache.EhCacheController"/>
    
    <cacheModel id="MyPojoCache" type="MapCacheController" readOnly="true" serialize="false">
    <property name="configFile" value="/ehcache.xml"/>
    </cacheModel>
    
    <resultMap id="ResultQueryMap" class="MyPojo">
    ...property mappings go here...
    </resultMap>
    
    <select id="getMyPojoList" resultMap="ResultQueryMap" cacheModel="MyPojoCache">
    ...select query to get your pojo from the database goes here...
    </select>
    
    </sqlMap>

and a sample eh-cache.xml file:

<ehcache>
    
    ...put your default cache here...
    
    <cache
    name="myNamespace.MyPojoCache"
    maxElementsInMemory="5"
    eternal="false"
    timeToLiveSeconds="60"
    overflowToDisk="false"
    memoryStoreEvictionPolicy="LRU"/>
    
    </ehcache>

Things to watch out for:

  • The configFile property in the <cacheMode> entry in the sqlMap.xml is a classpath resource.
  • You can add more <cacheModel> entries to your sqlMap.xml, all pointing to the same <MapCacheController>. Since the CacheManager is intialized as a Singleton, this will cause multiple config calls needlessly, but it is only a startup issue.
  • make sure you enable cacheModelsEnabled=true attribute in your <settings> in the sqlMapConfig.xml otherwise the caching won't be enabled at all.

For questions please mail me at michel.schudel@gmail.com


Site running on a free Atlassian Confluence Open Source Project License granted to OSS. Evaluate Confluence today.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.5.5 Build:#811 Jul 25, 2007) - Bug/feature request - Contact Administrators