public abstract class AbstractCacheWorker<T, Z> {
@Resource
protected RedisCommand redisCommand;
/**
* 读Redis缓存的实现
*
* @param z 输入参数
* @return
*/
protected T read(Z z) {
throw new IllegalArgumentException("read 方法未定义" + z);
}
/**
* 批量读redis缓存的实现
*
* @param z 输入参数
* @return 输出读取结果
*/
protected List<T> batchRead(List<Z> z) {
throw new IllegalArgumentException("batchRead 方法未定义" + z);
}
/**
* 回源并写Redis缓存的实现
*
* @param z 输入参数
* @return 输出回源结果
*/
protected T write(Z z) {
throw new IllegalArgumentException("write 方法未定义" + z);
}
/**
* 回源并写Redis缓存的实现,自定义时间 Athony
*
* @param z
* @param s 时间
* @return
*/
protected boolean write(Z z, int s) {
throw new IllegalArgumentException("write 方法未定义" + z);
}
/**
* 批量回源并写Redis缓存的实现
*
* @param z 输入参数
* @return 输出回源结果
*/
private Map<Z, T> batchWrite(List<Z> z, List<Integer> pos) {
// 1.
List<Z> keyOfNeedWriteList = new ArrayList<Z>(pos.size());
for (Integer i : pos) {
keyOfNeedWriteList.add(z.get(i));
}
return batchWrite(keyOfNeedWriteList);
}
protected Map<Z, T> batchWrite(List<Z> z) {
throw new IllegalArgumentException("batchWrite 方法未定义");
}
/**
* 单条回源后,立即执行方法入口
*
* @param t 输入对象
* @return 输出对象
*/
protected T beforeReturn(T t) {
return t;
}
/**
* 批量回源后,立即执行方法入口
*
* @param list 输入对象
* @return 输出对象
*/
protected List<T> beforeBatchReturn(List<T> list) {
return list;
}
/**
* 执行批量查询的方法
*
* @param list 输入参数
* @return 结果
*/
@SuppressWarnings("all")
public List<T> batchFind(List<Z> list) {
if (list == null || list.isEmpty()) {
return new ArrayList<T>();
}
List<T> tList = batchRead(list);
List<Integer> posList = nullPos(tList);
if (!posList.isEmpty()) {
Map<Z, T> tmpMap = batchWrite(list, posList);
for (int i = 0; i < posList.size(); i++) {
int pos = posList.get(i);
tList.set(pos, tmpMap.get(list.get(pos)));
}
}
return beforeBatchReturn(tList);
}
/**
* 执行单条查询的方法
*
* @param z 输入参数
* @return 结果
*/
@SuppressWarnings("all")
public T find(Z z) {
if (z == null) {
return null;
}
T t = read(z);
if (t == null) {
t = write(z);
}
return beforeReturn(t);
}
/**
* 计算列表中为null的各元素位置
*
* @param t 列表
* @return null元素位置列表
*/
private List<Integer> nullPos(List<T> t) {
List<Integer> posList = new ArrayList<Integer>();
for (int i = 0; i < t.size(); i++) {
if (t.get(i) == null) {
posList.add(i);
}
}
return posList;
}
}
单查
find
/**
* 执行单条查询的方法
*
* @param z 输入参数
* @return 结果
*/
@SuppressWarnings("all")
public T find(Z z) {
if (z == null) {
return null;
}
T t = read(z);
if (t == null) {
t = write(z);
}
return beforeReturn(t);
}* 1) 读取 -(未找到)-> 回源 -> 写入 -> 返回<br>
* 2) 读取 -(找到)-> 返回
write
读链路如果检索到缓存中没有相关数据就会触发写链路
1)数据库中有对应数据 -> 批量写数据并设置过期时间 -> 返回结果
2)数据库中没有对应的数据 -> 设置相应的empty-key防止重复请求数据库.按照这种操作方式,需要在数据库中数据变更时,将对应的key和empty-key都删除,防止数据不同步 ->返回空结果
@Override
protected T write(Z z) {
String redisKey = "";
String emptyKey = "";
String result = testDao.get(z);
if (StrUtil.isBlank(result)){
redisCommand.set(emptyKey,"");
return empty_T;
}
redisCommand.set(redisKey,result);
return T;
}read
缓存中有key或者empty-key -> 查询key -> 查询结果为空,证明时empty-key -> 返回empty -> 不需要查询数据库 -> 返回空结果
缓存中有key或者empty-key -> 查询key -> 查询结果不为空 -> 返回查询结果
缓存中没有 key和enpty-key -> 写链路写入相应的key或者empty-key -> 写链路返回结果
@Override
protected T read(Z z) {
String rediskey = "";
String emptyKey = "";
if (redisCommand.exists(emptyKey) || redisCommand.exists(rediskey)){
String s = redisCommand.get(rediskey);
if (StrUtil.isBlank(s)){
return empty_T;
}
return T;
}
return null;
}beforeReturn
单挑记录查询之后立即执行beforeReturn中的方法。默认为空,可以自行织入相关逻辑
版权声明:本文为weixin_52469898原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。