Redis使用zset集合根据分值实现分页功能

自己去看代码吧

@Component
public class QueryPage {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    private final String KEY="query:shop";

    /**
     * 向zset集合添加测试数据
     * */
    public void addData(){
        int score=0;
        int currentScore=0;
        for(int k=0;k<20;k++){
            currentScore=score;
            if(k%4==0){
                currentScore--;
            }
            stringRedisTemplate.opsForZSet().incrementScore(KEY,"shop:"+k,currentScore);
            score++;
            System.out.println("value:"+"shop:"+k+"  score:"+currentScore);
        }
    }

    /**
     * 查询小于等于max分值的数据,offset是偏移量
     * 第一次查询max可以赋予最大值999999999,offset赋值0
     * 后面翻页使用上次返回结果为max和offset赋值
     * */
    public Map<String,Object> query(long max,int offset){
        Map<String,Object> result=new HashMap<>();
        //查询分值小于等于max且最小值大于等于0的数据,查询3条
        //offset是偏移量,如数据中倒序的分值分别为5,5,4,4,3,3,2,,1,1
        //第一页查询offset=0结果为5,5,4
        //第二页查询offset=1结果为4,3,3 因为第一页中已经有4所以本次查询要把上次出现4的此次赋值给offset
        Set<ZSetOperations.TypedTuple<String>> typedTuples=stringRedisTemplate.opsForZSet().reverseRangeByScoreWithScores(KEY,0,max,offset,3);
        if(typedTuples == null || typedTuples.isEmpty()){
            // -1.表示没有数据
            return null;
        }
        //解析数据
        List<String> ids=new ArrayList<>(typedTuples.size());
        int minScore=0;
        int os=1;
        for(ZSetOperations.TypedTuple<String> tuple:typedTuples){
            //获取数据
            ids.add(tuple.getValue());
            //获取分值
            int score=tuple.getScore().intValue();
            if(score==minScore){
                os++;
            }else{
                minScore=score;
                os=1;
            }
        }
        result.put("offset",os);//用于后面翻页作为offset参数的值
        result.put("max",minScore);//用于后面翻页作为max参数的值
        result.put("data",ids);//查询到的数据
        return result;
    }
}

创建测试数据调用

addData()

翻页调用

//首页
Map<String,Object> result=query(99999,0);
//后面页使用上次返回的结果作为参数
int max=Integer.valueOf(result.get("max").toString()).intValue();
int offset=Integer.valueOf(result.get("offset").toString()).intValue();
Map<String,Object> other=query(max,offset);
posted @ 2023-01-06 18:11  big-strong-yu  阅读(513)  评论(0编辑  收藏  举报