使用redis实现滚动分页效果

滚动分页

我们在刷朋友圈或者微博的时候, 默认是显示了一部分, 当我们下拉的时候会动态展示出以后的内容

使用场景

  1. 朋友圈
  2. 微博
  3. 评论区

实现原理

  1. 点击进入后会初始化出最新的几条
  2. 当触发下拉时, 返回新的几条.
难点: 如果此时有新数据插入防止重复?
  1. 使用redis中的 z-set保存数据.
    key为 userId,
    value为 内容编号,
    score为时间戳
  2. 使用reverseRangeByScoreWithScores获取,每次获取数据时, 传入最小score, 再次查询时, 从入参score后开始查询.
  3. score重复的情况. reverseRangeByScoreWithScores提供了偏移量参数offset, 可以统计算偏移量,解决数据重复的问题

ZSET的reverseRangeByScoreWithScores

根据分数倒序排列

入参
key: 就是主键, 本次是userId
min: 最小分数. 本次用不上, 因为我们倒序查询, 有最大分数 和 count查询多少条就够了
max: 最大分数 倒序查询的起点
offset: 偏移量 如果偏移量是0, 就从此数据开始查(包含此数据), 1 从此数据后+1开始.以此类推…
count: 总共查询多少条

示例代码

 String userId = UserHolder.getUser().getId().toString();
        /**
         * rangeByScore参数:
         *      1. key 主键
         *      2. 分数最小值  因为本次分数是用的时间,倒叙 所以不用考虑最小值 ,填写0
         *      3. 分数最大值  前端传过来的上次的最小时间
         *      4. 偏移量 如果是0 就是<=. 如果是1 就是<  如果是2 就是比它小两个的  时间戳是不同的,所以不用考虑分数相同的情况
         *      5. 总共查询几条
         */

        Set<ZSetOperations.TypedTuple<String>> tuples = stringRedisTemplate.opsForZSet().reverseRangeByScoreWithScores(FEED_KEY + userId, 0, lastId, offset, 2);
        if (tuples == null || tuples.isEmpty()) {
            return Result.ok();
        }
        //计算下次偏移量
        int targetOffset = 1;
        //计算下次的开始分数
        long targetLastTime = 0L;
        ArrayList<Long> ids = new ArrayList<>();
        
        for (ZSetOperations.TypedTuple<String> tuple : tuples) {
            ids.add(Long.valueOf(tuple.getValue()));
            long time = tuple.getScore().longValue();
            if (time == targetLastTime) {
                targetOffset++;
            } else {
                targetLastTime = time;
                targetOffset = 1;
            }
        }

你可能感兴趣的:(redis,数据库,缓存)