redis分页查询案例

redis的分页查询利用到了sortset 和 hash的两个数据类型,这两个互相配合使用才能完美的完成分页,思想都在都在代码中

1.初始逻辑

@Override
    public List<User> selectAll() {
        long page = 2;
        long pageSize = 4;
        String key = "user_key_";
        List<User> users = new ArrayList<>();
        if (!redisTemplate.hasKey(key)) {
            users = userMapper.selectAll();
            for (User user : users) {
                //初始化user_key的索引,利用sortset来保存hk每个对象的hk
          redisTemplate.opsForZSet().add("sortId", key + user.getId(), user.getId());
               //利用hash来保存user,这里的hk要和sortset保存的value一致,后续分页的时候有用
                redisTemplate.opsForHash().put(key, key + user.getId(), user);
            }
            return users;
        }else {
            //获得最后一个对应的member,用于获得最大的分数
              Set<String> sortId = redisTemplate.opsForZSet().reverseRange("sortId", 0, 0);
            String hkey = sortId.iterator().next();
         //根据member获得最大分值
         Double maxScore = redisTemplate.opsForZSet().score("sortId", hkey);
       // 分页取数据
       Set<String> sets =  redisTemplate.opsForZSet().rangeByScore("sortId",0,maxScore,(page-1)*pageSize,page*pageSize);
       List list = new ArrayList(sets);
            System.out.println(sets);
        //批量根据获得的key批量获取
            users = redisTemplate.opsForHash().multiGet(key,list);

            return users;
        }

    }
}

2.优化后
1.创建RedisUtil


@Component
public class RedisUtil {
    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    /**
     * 获得最大分数
     * @param key
     * @return
     */
    public Double sMaxScore(String key){
        //获得最后一个对应的member,用于获得最大的分数
        Set<String> sortId = redisTemplate.opsForZSet().reverseRange(key, 0, 0);
        String hkey = sortId.iterator().next();
        //根据member获得最大分值
        Double maxScore = redisTemplate.opsForZSet().score(key, hkey);
        return maxScore;
    }

    /**
     * 分页获取成员
     * @param key
     * @param min 最小分数
     * @param max 最大分数
     * @param pageStart
     * @param pageSize
     * @return
     */
    public List sRangeByScore(String key,Double min,Double max,Long pageStart,Long pageSize){
        // 分页取数据
        Set<String> sets =  redisTemplate.opsForZSet().rangeByScore(key,min,max,(pageStart-1)*pageSize,pageStart*pageSize);
        List list = new ArrayList(sets);

        return list;
    }

    /**
     * 批量获得数据
     * @param key
     * @param hkeys
     * @return
     */
    public List hMultiGet(String key , List hkeys){
          return redisTemplate.opsForHash().multiGet(key, hkeys);
    }
}

2.selectAll()方法

@Override
public List<User> selectAll() {
    long page = 1;
    long pageSize = 30;
    String key = "user_key_";
    List<User> users = null;
    if (redisTemplate.hasKey(key)) {
        //获得最大分值
        Double maxScore =  redisUtil.sMaxScore("sortId");
        // 分页取数据
        List list = redisUtil.sRangeByScore("sortId",0.0,maxScore,page,pageSize);
        users =redisUtil.hMultiGet(key,list);
        return users;
    }else {
        users = userMapper.selectAll();
        for (User user : users) {
            //初始化user_key的索引
            redisTemplate.opsForZSet().add("sortId", key + user.getId(), user.getId());
            redisTemplate.opsForHash().put(key, key + user.getId(), user);
        }
        return users;
    }

}

有不足的地方请多多指教

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值