Redis读写模板类

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中的方法。默认为空,可以自行织入相关逻辑

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值