ibatis基础上添加memcached缓存

在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>

然后配置sqlMapConfig.xml文件:<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPEsqlMapConfigPUBLIC"-//iBATIS.com//DTDSQLMapConfig2.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>
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; 
        } 
}

相关推荐