真正的mybatis_redis二级缓存
网上流传的代码缓存失效存在严重问题。
思路....以后再细说
目前的方案还不够完美,失效力度控制不够细。
主要代码
import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.util.Properties; 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.apache.log4j.Logger; import redis.clients.jedis.Jedis; /* * 使用第三方缓存服务器,处理二级缓存 * zuimao */ public class RedisCache implements Cache { private static final Logger logger = Logger.getLogger(RedisCache.class); /** The ReadWriteLock. */ private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); private final String COMMON_CACHE_KEY = "MYBATIS:"; private static final String UTF_8 = "utf-8"; /** * 按照一定规则标识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 + ":*"; } private String id; public RedisCache() { } public RedisCache(final String id) { if (id == null) { throw new IllegalArgumentException("必须传入ID"); } 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; try { jedis = RedisStandAloneUtil.getJedisPool().getResource(); Set<byte[]> keys = jedis.keys(getKeys().getBytes(UTF_8)); if (null != keys && !keys.isEmpty()) { result = keys.size(); } logger.debug(this.id+"---->>>>总缓存数:" + result); } catch (Exception e) { logger.error(e.getMessage(), e); } finally { if (jedis != null) { jedis.close(); } } return result; } @Override public void putObject(Object key, Object value) { Jedis jedis = null; try { jedis = RedisStandAloneUtil.getJedisPool().getResource(); byte[] keys = getKey(key).getBytes(UTF_8); jedis.set(keys, SerializeUtil.serialize(value)); logger.debug("添加缓存--------"+this.id); //getSize(); } catch (Exception e) { logger.error(e.getMessage(), e); } finally { if (jedis != null) { jedis.close(); } } } @Override public Object getObject(Object key) { Jedis jedis = null; Object value = null; try { jedis = RedisStandAloneUtil.getJedisPool().getResource(); value = SerializeUtil.unserialize(jedis.get(getKey(key).getBytes(UTF_8))); logger.debug("从缓存中获取-----"+this.id); //getSize(); } catch (Exception e) { logger.error(e.getMessage(), e); } finally { if (jedis != null) { jedis.close(); } } return value; } @Override public Object removeObject(Object key) { Jedis jedis = null; Object value = null; try { jedis = RedisStandAloneUtil.getJedisPool().getResource(); value = jedis.del(getKey(key).getBytes(UTF_8)); logger.debug("LRU算法从缓存中移除-----"+this.id); //getSize(); } catch (Exception e) { logger.error(e.getMessage(), e); } finally { if (jedis != null) { jedis.close(); } } return value; } @Override public void clear() { Jedis jedis = null; try { jedis = RedisStandAloneUtil.getJedisPool().getResource(); Set<byte[]> keys = jedis.keys(getKeys().getBytes(UTF_8)); logger.debug("出现CUD操作,清空对应Mapper缓存======>"+keys.size()); for (byte[] key : keys) { jedis.del(key); } //下面是网上流传的方法,极大的降低系统性能,没起到加入缓存应有的作用,这是不可取的。 //jedis.flushDB(); //jedis.flushAll(); } catch (Exception e) { logger.error(e.getMessage(), e); } finally { if (jedis != null) { jedis.close(); } } } @Override public ReadWriteLock getReadWriteLock() { return readWriteLock; } }
作者:青羽