IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    [原]ibatis.cache接口实现:RedisCache,MemcachedCache,EhcacheCache

    undoner发表于 2017-01-22 16:01:50
    love 0

    (1)首先是Cache接口定义:

    package org.apache.ibatis.cache;
    
    import java.util.concurrent.locks.ReadWriteLock;
    
    public interface Cache {
    
      String getId();
    
      int getSize();
    
      void putObject(Object key, Object value);
    
      Object getObject(Object key);
    
      Object removeObject(Object key);
    
      void clear();
    
      ReadWriteLock getReadWriteLock();
    
    }

    (2)RedisCache接口实现:

    package cn.lsoft.undoner.dao.cache;
    
    import java.util.Set;
    import java.util.concurrent.locks.ReadWriteLock;
    import java.util.concurrent.locks.ReentrantReadWriteLock;
    
    import org.apache.commons.codec.digest.DigestUtils;
    import org.apache.ibatis.cache.Cache;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import cn.lsoft.undoner.util.SerializeUtil;
    import redis.clients.jedis.Jedis;
    import redis.clients.jedis.JedisPool;
    import redis.clients.jedis.JedisPoolConfig;
    
    /*
     * 使用第三方缓存服务器,处理二级缓存
     */
    public class RedisCache implements Cache {
    
    	private static Logger logger = LoggerFactory.getLogger(RedisCache.class);
    
    	/** The ReadWriteLock. */
    	private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    	private String id;
    	private JedisPool jedisPool;
    	private static final int DB_INDEX = 1;
    	private final String COMMON_CACHE_KEY = "COM:";
    	private static final String UTF8 = "utf-8";
    
    	private ApplicationContext context;
    
    	/**
    	 * 按照一定规则标识key
    	 */
    	private String getKey(Object key) {
    		StringBuilder accum = new StringBuilder();
    		accum.append(COMMON_CACHE_KEY);
    		accum.append(this.id).append(":");
    		accum.append(DigestUtils.md5Hex(String.valueOf(key)));
    		return accum.toString();
    	}
    
    	/**
    	 * redis key规则前缀
    	 */
    	private String getKeys() {
    		return COMMON_CACHE_KEY + this.id + ":*";
    	}
    
    	public RedisCache() {
    
    	}
    
    	public RedisCache(final String id) {
    		if (id == null) {
    			throw new IllegalArgumentException("必须传入ID");
    		}
    		context = new ClassPathXmlApplicationContext("/spring/spring-db-redis-context.xml");
    		JedisPoolConfig jedisPoolConfig = (JedisPoolConfig) context.getBean("poolConfig");
    		jedisPool = new JedisPool(jedisPoolConfig, "23.45.6.7", 6379);
    		logger.debug(">>>>>>>>>>>>>>>>>>>>>MybatisRedisCache:id=" + id);
    		this.id = id;
    	}
    
    	@Override
    	public String getId() {
    		return this.id;
    	}
    
    	@Override
    	public int getSize() {
    		Jedis jedis = null;
    		int result = 0;
    		boolean borrowOrOprSuccess = true;
    		try {
    			jedis = jedisPool.getResource();
    			jedis.select(DB_INDEX);
    			Set<byte[]> keys = jedis.keys(getKeys().getBytes(UTF8));
    			if (null != keys && !keys.isEmpty()) {
    				result = keys.size();
    			}
    			logger.debug(this.id + "---->>>>总缓存数:" + result);
    		} catch (Exception e) {
    			borrowOrOprSuccess = false;
    			if (jedis != null)
    				jedisPool.returnBrokenResource(jedis);
    		} finally {
    			if (borrowOrOprSuccess)
    				jedisPool.returnResource(jedis);
    		}
    		return result;
    	}
    
    	@Override
    	public void putObject(Object key, Object value) {
    		Jedis jedis = null;
    		boolean borrowOrOprSuccess = true;
    		try {
    			jedis = jedisPool.getResource();
    			jedis.select(DB_INDEX);
    
    			byte[] keys = getKey(key).getBytes(UTF8);
    			jedis.set(keys, SerializeUtil.serialize(value));
    			logger.debug("添加缓存--------" + this.id + " | " +keys.toString() + ":" + value.toString() );
    			getSize();
    		} catch (Exception e) {
    			borrowOrOprSuccess = false;
    			if (jedis != null)
    				jedisPool.returnBrokenResource(jedis);
    		} finally {
    			if (borrowOrOprSuccess)
    				jedisPool.returnResource(jedis);
    		}
    	}
    
    	@Override
    	public Object getObject(Object key) {
    		Jedis jedis = null;
    		Object value = null;
    		boolean borrowOrOprSuccess = true;
    		try {
    			jedis = jedisPool.getResource();
    			jedis.select(DB_INDEX);
    			byte[] keys = getKey(key).getBytes(UTF8);
    			value = SerializeUtil.unserialize(jedis.get(getKey(key).getBytes(UTF8)));
    			logger.debug("从缓存中获取-----" + this.id + " | "+keys.toString() + ":"  + value.toString());
    			getSize();
    		} catch (Exception e) {
    			borrowOrOprSuccess = false;
    			if (jedis != null)
    				jedisPool.returnBrokenResource(jedis);
    		} finally {
    			if (borrowOrOprSuccess)
    				jedisPool.returnResource(jedis);
    		}
    		return value;
    	}
    
    	@Override
    	public Object removeObject(Object key) {
    		Jedis jedis = null;
    		Object value = null;
    		boolean borrowOrOprSuccess = true;
    		try {
    			jedis = jedisPool.getResource();
    			jedis.select(DB_INDEX);
    			byte[] keys = getKey(key).getBytes(UTF8);
    			value = jedis.del(getKey(key).getBytes(UTF8));
    			logger.debug("LRU算法从缓存中移除-----" + this.id + " | " +keys.toString() + ":" + value.toString());
    			getSize();
    		} catch (Exception e) {
    			borrowOrOprSuccess = false;
    			if (jedis != null)
    				jedisPool.returnBrokenResource(jedis);
    		} finally {
    			if (borrowOrOprSuccess)
    				jedisPool.returnResource(jedis);
    		}
    		return value;
    	}
    
    	@Override
    	public void clear() {
    		Jedis jedis = null;
    		boolean borrowOrOprSuccess = true;
    		try {
    			jedis = jedisPool.getResource();
    			jedis.select(DB_INDEX);
    			// 如果有删除操作,会影响到整个表中的数据,因此要清空一个mapper的缓存(一个mapper的不同数据操作对应不同的key)
    			Set<byte[]> keys = jedis.keys(getKeys().getBytes(UTF8));
    			logger.debug("出现CUD操作,清空对应Mapper缓存======>" + keys.size());
    			for (byte[] key : keys) {
    				jedis.del(key);
    			}
    			// 下面是网上流传的方法,极大的降低系统性能,没起到加入缓存应有的作用,这是不可取的。
    			// jedis.flushDB();
    			// jedis.flushAll();
    		} catch (Exception e) {
    			borrowOrOprSuccess = false;
    			if (jedis != null)
    				jedisPool.returnBrokenResource(jedis);
    		} finally {
    			if (borrowOrOprSuccess)
    				jedisPool.returnResource(jedis);
    		}
    	}
    
    	@Override
    	public ReadWriteLock getReadWriteLock() {
    		return readWriteLock;
    	}
    }

    (3)MemcachedCache接口实现:

    package org.mybatis.caches.memcached;
    
    import java.util.concurrent.locks.ReadWriteLock;
    
    import org.apache.ibatis.cache.Cache;
    
    /**
     * The Memcached-based Cache implementation.
     *
     * @author Simone Tripodi
     */
    public final class MemcachedCache implements Cache {
    
        private static final MemcachedClientWrapper MEMCACHED_CLIENT = new MemcachedClientWrapper();
    
        /**
         * The {@link ReadWriteLock}.
         */
        private final ReadWriteLock readWriteLock = new DummyReadWriteLock();
    
        /**
         * The cache id.
         */
        private final String id;
    
        /**
         * Builds a new Memcached-based Cache.
         *
         * @param id the Mapper id.
         */
        public MemcachedCache(final String id) {
            this.id = id;
        }
    
        /**
         * {@inheritDoc}
         */
        public void clear() {
            MEMCACHED_CLIENT.removeGroup(this.id);
        }
    
        /**
         * {@inheritDoc}
         */
        public String getId() {
            return this.id;
        }
    
        /**
         * {@inheritDoc}
         */
        public Object getObject(Object key) {
            return MEMCACHED_CLIENT.getObject(key);
        }
    
        /**
         * {@inheritDoc}
         */
        public ReadWriteLock getReadWriteLock() {
            return this.readWriteLock;
        }
    
        /**
         * {@inheritDoc}
         */
        public int getSize() {
            return Integer.MAX_VALUE;
        }
    
        /**
         * {@inheritDoc}
         */
        public void putObject(Object key, Object value) {
            MEMCACHED_CLIENT.putObject(key, value, this.id);
        }
    
        /**
         * {@inheritDoc}
         */
        public Object removeObject(Object key) {
            return MEMCACHED_CLIENT.removeObject(key);
        }
    
    }
    

    (3)EhcacheCache接口实现:

    package org.mybatis.caches.ehcache;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.concurrent.locks.ReadWriteLock;
    import java.util.concurrent.locks.ReentrantReadWriteLock;
    
    import net.sf.ehcache.CacheManager;
    import net.sf.ehcache.Ehcache;
    import net.sf.ehcache.Element;
    
    import org.apache.ibatis.cache.Cache;
    import org.apache.ibatis.cache.CacheException;
    
    /**
     * Cache adapter for Ehcache.
     *
     * @version $Id: EhcacheCache.java 3454 2010-12-29 20:35:44Z simone.tripodi $
     */
    public final class EhcacheCache implements Cache {
    
        /**
         * The cache manager reference.
         */
        private static final CacheManager CACHE_MANAGER = createCacheManager();
    
        /**
         * Looks for "/ehcache.xml" classpath resource and builds the relative
         * {@code CacheManager}; if it's no found or it is impossible to load it,
         * returns the default manager.
         *
         * @return the application cache manager.
         */
        private static CacheManager createCacheManager() {
            CacheManager cacheManager;
            InputStream input = EhcacheCache.class.getResourceAsStream("/ehcache.xml");
    
            if (input != null) {
                try {
                    cacheManager = CacheManager.create(input);
                } catch (Throwable t) {
                    cacheManager = CacheManager.create();
                } finally {
                    try {
                        input.close();
                    } catch (IOException e) {
                    }
                }
            } else {
                cacheManager = CacheManager.create();
            }
    
            return cacheManager;
        }
    
        /**
         * The {@code ReadWriteLock}.
         */
        private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    
        /**
         * The cache id.
         */
        private final String id;
    
        /**
         *
         *
         * @param id
         */
        public EhcacheCache(final String id) {
            if (id == null) {
                throw new IllegalArgumentException("Cache instances require an ID");
            }
            this.id = id;
            if (!CACHE_MANAGER.cacheExists(this.id)) {
                CACHE_MANAGER.addCache(this.id);
            }
        }
    
        /**
         * {@inheritDoc}
         */
        public void clear() {
            this.getCache().removeAll();
        }
    
        /**
         * {@inheritDoc}
         */
        public String getId() {
            return this.id;
        }
    
        /**
         * {@inheritDoc}
         */
        public Object getObject(Object key) {
            try {
                Element cachedElement = this.getCache().get(key.hashCode());
                if (cachedElement == null) {
                    return null;
                }
                return cachedElement.getObjectValue();
            } catch (Throwable t) {
                throw new CacheException(t);
            }
        }
    
        /**
         * {@inheritDoc}
         */
        public ReadWriteLock getReadWriteLock() {
            return this.readWriteLock;
        }
    
        /**
         * {@inheritDoc}
         */
        public int getSize() {
            try {
                return this.getCache().getSize();
            } catch (Throwable t) {
                throw new CacheException(t);
            }
        }
    
        /**
         * {@inheritDoc}
         */
        public void putObject(Object key, Object value) {
            try {
                this.getCache().put(new Element(key.hashCode(), value));
            } catch (Throwable t) {
                throw new CacheException(t);
            }
        }
    
        /**
         * {@inheritDoc}
         */
        public Object removeObject(Object key) {
            try {
                Object obj = this.getObject(key);
                this.getCache().remove(key.hashCode());
                return obj;
            } catch (Throwable t) {
                throw new CacheException(t);
            }
        }
    
        /**
         * Returns the ehcache manager for this cache.
         *
         * @return the ehcache manager for this cache.
         */
        private Ehcache getCache() {
            return CACHE_MANAGER.getCache(this.id);
        }
    
        /**
         * {@inheritDoc}
         */
        @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());
        }
    
        /**
         * {@inheritDoc}
         */
        @Override
        public int hashCode() {
            return this.id.hashCode();
        }
    
        /**
         * {@inheritDoc}
         */
        @Override
        public String toString() {
            return "EHCache {"
                    + this.id
                    + "}";
        }
    
    }
    





沪ICP备19023445号-2号
友情链接