springboot使用scan命令实现redis模糊匹配分页查询(附代码)

一.scan前言

  • 从Redis v2.8开始,SCAN命令已经可用,它允许使用游标从keyspace中检索键。
    对比KEYS命令,虽然SCAN无法一次性返回所有匹配结果,但是却规避了阻塞系统这个高风险,从而也让一些操作可以放在主节点上执行。

二. 需求说明

  • 公司项目是内网系统,没有并发量,由于第三方接口响应太慢,该接口的数据需频繁使用。项目经理强烈不满,认为应该效率换内存空间,要求数据时效性T+1,于是就有了将接口数据的所需字段存入redis中,每日增量更新。

三.使用scan命令实现redis模糊匹配分页查询

  • 根据查询关键字分页获取key集合
/**
     * 根据查询关键字分页获取key集合
     * @param patternKey 查询关键字,模糊匹配的key
     * @param pageNum 页号
     * @param pageSize 页大小
     * @return 匹配到的keys
     */
    private List<String> findKeysForPage(String patternKey, int pageNum, int pageSize) {
        ScanOptions options = ScanOptions.scanOptions().match(patternKey).count(10000).build();
        RedisConnectionFactory factory = redisTemplate.getConnectionFactory();
        RedisConnection rc = factory.getConnection();
        Cursor<byte[]> cursor = rc.scan(options);
        List<String> result = new ArrayList<String>(pageSize);
        int tmpIndex = 0;
        int startIndex = (pageNum - 1) * pageSize;  // 开始节点
        int end = pageNum * pageSize;   // 去redis中找的次数,结束节点
        while (cursor.hasNext()) {
            if (tmpIndex >= startIndex && tmpIndex < end) {
                byte[] key = cursor.next();
                if (key == null || key.length == 0) {
                    break;
                }
                String keyStr = new String(key);
                result.add(keyStr);
                tmpIndex++;
                continue;
            }
            // 要获取总条数, 就注释掉
            if (tmpIndex >= end) {
                break;
            }

            tmpIndex++;
            cursor.next();
        }
        try {
            cursor.close();
        } catch (Exception e) {
            e.printStackTrace();
            log.error("cursor.close(); redis连接关闭异常 {}", e.getMessage());
        }

        try {
            RedisConnectionUtils.releaseConnection(rc, factory);
        } catch (Exception e) {
            e.printStackTrace();
            log.error(" RedisConnectionUtils.releaseConnection(rc, factory); redis连接关闭异常 {}", e.getMessage());
        }
        return result;
    }
  • 根据keys获取数据列表
/**
     * 根据keys获取数据列表
     * @param keyList
     * @return List
     */
    public List getListByKeys(List keyList) {
        return redisTemplate.opsForValue().multiGet(keys);
    }
  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值