真正的mybatis_redis二级缓存

时间:2023-03-09 13:23:37
真正的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;
} }