q9989 发表于 2016-11-25 08:56:51

用GemFire做Mybatis二级缓存

  转自:http://blog.sina.com.cn/s/blog_72ef7bea0101basm.html
  MyBatis支持第三方二级缓存实现,目前支持Ehcache、Hazelcast和OSCache。
  GemFire不在支持的范围,但是可以通过实现org.apache.ibatis.cache.Cache接口来使用。


1、设置MyBatis的Cache全局使用开关:默认是true,如果它配成false,其余各个Mapper XML文件配成支持cache也没用。

<settings>
   <setting name="cacheEnabled" value="true"/>
</settings>




2、各个Mapper XML文件,默认是不采用cache。在配置文件加一行就可以支持cache:

<mapper namespace="org.acme.FooMapper">

    <cache type="com.yqu.mybatis.caches.gemfire.GemfireCache"/>

    ...

</mapper>




3、实现GemfireCache

package com.yqu.mybatis.caches.gemfire;

import com.gemstone.gemfire.cache.AttributesFactory;
import com.gemstone.gemfire.cache.CacheFactory;
import com.gemstone.gemfire.cache.Region;

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.apache.ibatis.cache.Cache;
import org.apache.ibatis.cache.CacheException;

public final class GemfireCache implements Cache {
    private static Region<Object, Object> mybatis_region = null;
    private Region<Object, Object> region = null;    
    private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    private String id;
    
    public void setId(String id) {
        this.id = id;
    }
    
    public void setRegion(Region<Object, Object> region) {
        this.region = region;
    }
    
    public Region<Object, Object> getRegion() {
        return region;
    }
    
    private static synchronized Region<Object, Object> getParentRegion()
    {
        if(mybatis_region==null)
        {
            com.gemstone.gemfire.cache.Cache cache = new CacheFactory()
                .set("name", "mybatis_gemfire_cache")
                .set("cache-xml-file", "gemfire.xml").create();
            mybatis_region = cache.getRegion("mybatis_gemfire_region");
        }
        return mybatis_region;
    }
    
    @SuppressWarnings({ "deprecation", "unchecked", "rawtypes" })
    public GemfireCache(String id) {
        if (id == null) {
            throw new IllegalArgumentException("Cache instances require an ID");
        }
        this.id = id;
                
        region = getParentRegion().getSubregion(id);
        if (null == region) {
            AttributesFactory attrFactory =
                    new AttributesFactory(mybatis_region.getAttributes());
            
            region = mybatis_region.createSubregion(id, attrFactory.create());
        }
    }
    
    public void clear() {
        if (null != region) {
            try {
                region.clear();
            } catch (Throwable t) {
                throw new CacheException(t);
            }    
        }
    }
    
    public String getId() {
        return this.id;
    }
    
    public Object getObject(Object key) {
        Object retVal = null;
        if (null != region) {
            if (region.containsKey(key.hashCode())) {
                try {
                    retVal = region.get(key.hashCode());
                } catch (Throwable t) {
                    throw new CacheException(t);
                }    
            }
        }
        return retVal;
    }
    
    public ReadWriteLock getReadWriteLock() {
        return this.readWriteLock;
    }
    
    public int getSize() {
        if (null != region) {
            try {
                return region.size();
            } catch (Throwable t) {
                throw new CacheException(t);
            }
        }
        return 0;
    }
    
    public void putObject(Object key, Object value) {
        if (null != region) {
            try {
                region.put(key.hashCode(), value);
            } catch (Throwable t) {
                throw new CacheException(t);
            }
        }
    }
    
    public Object removeObject(Object key) {
        if (null != region) {
            try {
                return region.remove(key.hashCode());
            } catch (Throwable t) {
                throw new CacheException(t);
            }
        }
        return null;
    }
    
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (!(obj instanceof Cache)) {
            return false;
        }
        
        Cache otherCache = (Cache)obj;
        return this.id.equals(otherCache.getId());
    }
    
    @Override
    public int hashCode() {
        return this.id.hashCode();
    }
    
    @Override
    public String toString() {
        return "GemfireCache{" + this.id + "}";
    }
}




4、Mapper XML文件配置支持cache后,文件中所有的Mapper statement就支持了。此时要个别对待某条可以通过useCache禁止使用cache:

<select id="inetAton" parameterType="string" resultType="integer" useCache=“false”>    
  select inet_aton(#{name})
</select>




参考  http://howtodoinjava.com/2013/01/06/how-to-enable-caching-in-ibatis-using-oscache/
  http://www.webdbtips.com/60455/
  http://blog.csdn.net/xuezhimeng/article/details/7378096
  http://grepcode.com/file/repo1.maven.org/maven2/org.mybatis.caches/mybatis-ehcache/1.0.0-RC1/org/mybatis/caches/ehcache/EhcacheCache.java
页: [1]
查看完整版本: 用GemFire做Mybatis二级缓存