在ibatis源码基础上修改,增加对memcached支持,通过配置IBatis的xml文件即可实现memcached细粒度话缓存,使用简单,缓存效果好。 spring下首先初始化MemcachedManager对象,或者通过程序初始化也一样,不要用ibatis官方的jar包,否则会冲突
- <bean class="com.ibatis.sqlmap.engine.cache.memcached.memcachedManager" lazy-init="false"
- init-method="init" destroy-method="closePool">
- <property name="serverlist">
- <value>
- 192.168.0.1:11111, 192.168.0.2:11111
- </value>
- </property>
- <property name="initConn" value="5">
- </property>
- <property name="minConn" value="5">
- </property>
- <property name="maxConn" value="200">
- </property>
- Unknown end tag for </bean>
<bean class="com.ibatis.sqlmap.engine.cache.memcached.memcachedManager" lazy-init="false"
init-method="init" destroy-method="closePool">
<property name="serverlist">
<value>
192.168.0.1:11111, 192.168.0.2:11111
</value>
</property>
<property name="initConn" value="5">
</property>
<property name="minConn" value="5">
</property>
<property name="maxConn" value="200">
</property>
Unknown end tag for </bean>
然后配置sqlMapConfig.xml文件: <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE sqlMapConfig PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"
"http://ibatis-with-memcached.googlecode.com/files/sql-map-config-2.dtd"> #注意这里,不用官方的,这个dtd文件加了个新属性databaseUrl,区分不同数据库的缓存对象
- <sqlmapconfig>
- <properties resource="cache_config.properties">
- </properties>
- <settings
- cacheModelsEnabled="true" enhancementEnabled="true" lazyLoadingEnabled="true" maxRequests="256" maxSessions="256" maxTransactions="150" useStatementNamespaces="true" databaseUrl="数据库名或地址" #新增加的属性 />
- ibatis的xml文件:Albums.xml #创建缓存model
- <cachemodel type="MEMCACHED" id="albumsCache">
- <flushinterval hours="12">
- </flushInterval >
- <flushonexecute statement="albums.save">
- </flushOnExecute >
- <flushonexecute statement="albums.update">
- </flushOnExecute >
- <flushonexecute statement="albums.delete">
- </flushOnExecute >
- <property name="pk" value="id">
- </property>
- #可以根据主键进行缓存,可以设置为空,不能不设
- <property name="groupField" value="accId">
- </property>
- #可以根据组(比如用户id)进行缓存,更加细粒度化,可以设置为空,不能不设
- Unknown end tag for </cachemodel>
- #加入缓存
- <select id="findall" parameterClass="albumsObj" resultClass="albumsObj" cacheModel="albumsCache">
- Select ……from albums where accId=1
- </select>
- <select id="load" parameterClass="albumsObj" resultClass="albumsObj" cacheModel="albumsCache">
- Select ……from albums where id=1
- </select>
- #删除对象,删除缓存
- <delete id="delete" parameterClass="albumsObj">
- delete from albums where id=1 and accId=1 #(加上accId可以删除分组缓存)
- </delete>
<sqlmapconfig>
<properties resource="cache_config.properties">
</properties>
<settings
cacheModelsEnabled="true" enhancementEnabled="true" lazyLoadingEnabled="true" maxRequests="256" maxSessions="256" maxTransactions="150" useStatementNamespaces="true" databaseUrl="数据库名或地址" #新增加的属性 />
ibatis的xml文件:Albums.xml #创建缓存model
<cachemodel type="MEMCACHED" id="albumsCache">
<flushinterval hours="12">
</flushInterval >
<flushonexecute statement="albums.save">
</flushOnExecute >
<flushonexecute statement="albums.update">
</flushOnExecute >
<flushonexecute statement="albums.delete">
</flushOnExecute >
<property name="pk" value="id">
</property>
#可以根据主键进行缓存,可以设置为空,不能不设
<property name="groupField" value="accId">
</property>
#可以根据组(比如用户id)进行缓存,更加细粒度化,可以设置为空,不能不设
Unknown end tag for </cachemodel>
#加入缓存
<select id="findall" parameterClass="albumsObj" resultClass="albumsObj" cacheModel="albumsCache">
Select ……from albums where accId=1
</select>
<select id="load" parameterClass="albumsObj" resultClass="albumsObj" cacheModel="albumsCache">
Select ……from albums where id=1
</select>
#删除对象,删除缓存
<delete id="delete" parameterClass="albumsObj">
delete from albums where id=1 and accId=1 #(加上accId可以删除分组缓存)
</delete>
- package com.ibatis.sqlmap.engine.cache.memcached;
- import java.io.Serializable;
- import java.util.Collection;
- import java.util.Date;
- import java.util.Map;
- import org.apache.log4j.Logger;
- import com.danga.MemCached.MemCachedClient;
- import com.danga.MemCached.SockIOPool;
- public class MemcachedManager {
- private static Logger logger = Logger.getLogger(MemcachedManager.class);
- private static String memcachedDomain = "IBATIS_CACHED"; // memcached 域名
- private String serverlist;
- private static MemCachedClient mcc = null;
- private SockIOPool pool = null;
- private int initConn = 5;
- private int minConn = 5;
- private int maxConn = 50;
- public void init() {
- if (mcc != null)
- return;
- logger.info("Initializing ibatis memcached start.");
- if (pool == null) {
- try {
- pool = SockIOPool.getInstance(memcachedDomain);
- pool.setServers(serverlist.split(","));
- if (!pool.isInitialized()) {
- pool.setInitConn(initConn);
- pool.setMinConn(minConn);
- pool.setMaxConn(maxConn);
- pool.setMaintSleep(30);
- pool.setNagle(false);
- pool.setSocketTO(60 * 60);
- pool.setSocketConnectTO(0);
- pool.initialize();
- }
- } catch (Exception ex) {
- logger.error(ex.getMessage());
- }
- }
- if (mcc == null) {
- mcc = new MemCachedClient(memcachedDomain);
- mcc.setCompressEnable(false);
- mcc.setCompressThreshold(0);
- }
- logger.info("Initializing youxigu Memcached ok!");
- }
- public void closePool() {
- pool.shutDown();
- mcc = null;
- pool = null;
- logger.info("Ibatis memcached pool closed");
- }
- public static boolean set(Object key, Serializable obj) {
- logger.debug("set key:" + getKey(key) + ", value:" + obj);
- try {
- return mcc.set(getKey(key), obj);
- } catch (Exception e) {
- logger.error("Pool set error!");
- e.printStackTrace();
- }
- return false;
- }
- public static boolean set(Object key, Serializable obj, long cacheTime) {
- try {
- return mcc.set(getKey(key), obj, new Date(cacheTime));
- } catch (Exception e) {
- logger.error("Pool set error!");
- e.printStackTrace();
- }
- return false;
- }
- public static void replace(int key, Serializable value, long cacheTime) {
- try {
- mcc.replace(getKey(key), value, new Date(cacheTime));
- } catch (Exception e) {
- logger.error(" pool set error!");
- }
- }
- public static Object get(Object key) {
- Object result = null;
- String realkey = getKey(key);
- try {
- result = mcc.get(realkey);
- } catch (Exception e) {
- e.printStackTrace();
- }
- logger.debug("get key:" + getKey(key) + ", value:" + result);
- return result;
- }
- public static void setCounter(Object key, long count) {
- try {
- mcc.storeCounter(getCountKey(key), count);
- } catch (Exception e) {
- logger.error("Pool setCounter error!");
- }
- }
- public static void addCounter(Object key) {
- if(mcc.get(getCountKey(key))==null){
- mcc.storeCounter(getCountKey(key), 0);
- }
- try {
- mcc.incr(getCountKey(key));
- } catch (Exception e) {
- logger.error("Pool setCounter error!");
- }
- }
- public static void decreaseCounter(Object key) {
- try {
- mcc.decr(getCountKey(key));
- } catch (Exception e) {
- logger.error("Pool setCounter error!");
- }
- }
- public static void addCounter(Object key, long addValue) {
- try {
- mcc.incr(getCountKey(key), addValue);
- } catch (Exception e) {
- logger.error(" pool setCounter error!");
- }
- }
- public static long getCounter(Object key) {
- long result = 0;
- try {
- result = mcc.getCounter(getCountKey(key));
- } catch (Exception e) {
- logger.error(e.getMessage());
- }
- return result;
- }
- public static boolean delete(Object key) {
- try {
- return mcc.delete(getKey(key));
- } catch (Exception e) {
- logger.error(e.getMessage());
- }
- return false;
- }
- public static long deleteCounter(Object key) {
- try {
- return mcc.decr(getCountKey(key));
- } catch (Exception e) {
- logger.error(" pool setCounter error!");
- }
- return 0;
- }
- public static void flushAll() {
- mcc.flushAll();
- }
- @SuppressWarnings("unchecked")
- public static long size(){
- long size=0L;
- Map<String,Map<String,String>> status=mcc.statsItems();
- Collection<Map<String,String>> values=status.values();
- for (Map<String,String> state:values) {
- String num=state.get("items:1:number");
- if(num==null)
- continue;
- size+=Long.parseLong(state.get("items:1:number"));
- }
- return size;
- }
- private static String getKey(Object key) {
- return memcachedDomain + "@" + key;
- }
- private static String getCountKey(Object key) {
- return memcachedDomain + "@" + key + "_count";
- }
- public void setServerlist(String serverlist) {
- this.serverlist = serverlist;
- }
- public void setInitConn(int initConn) {
- this.initConn = initConn;
- }
- public void setMinConn(int minConn) {
- this.minConn = minConn;
- }
- public void setMaxConn(int maxConn) {
- this.maxConn = maxConn;
- }
- public void setMemcachedDomain(String memcachedKey) {
- MemcachedManager.memcachedDomain = memcachedKey;
- }
- }