基於redis實現排行榜

最近由於公司業務,需要對用戶邀請新人做排名統計,開始用了sql做了統計展示,後覺得每次刷新排行榜都需要去數據庫中查詢,不僅影響性能,效率可能也不是很好。後瞭解到可以使用redis zset做排名統計,故此記錄。

/**
     * 功能描述 將數據緩存到redis中
     * @author zm
     * @date 2019/9/23 10:15 
     * @param  userInfo
     agentCount
     * @return void
     */
    private void setRedisUserRankInfo(UserInfo userInfo, Integer count){
        try {
            Map<String, Object> userInfoMap = new HashMap<>();
            userInfoMap.put("nickName",userInfo.getUserName());
            userInfoMap.put("headImg", userInfo.getAvatar());
            redisTemplate.opsForZSet().add(REDISKEY,userInfo.getUserId(),count.doubleValue());
            redisTemplate.opsForValue().set(REDISKEY+"_"+userInfo.getUserId(),JSON.toJSONString(userInfoMap));
        } catch (Exception e) {
            log.error("信息存入redis異常",e);
        }
    }
/**
     * 功能描述 獲取排行榜
     * @author zm
     * @date 2019/9/23 10:27 
     * @param  
     * @return java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
     */
    private List<Map<String,Object>> getRankList(){
        List<Map<String,Object>> rank = new ArrayList<>();
        Set<ZSetOperations.TypedTuple<String>> typedTuples = redisTemplate.opsForZSet().reverseRangeByScoreWithScores(REDISKEY, 0, 99999, 0, 10);//只取前十條
        int index = 0;
        for(ZSetOperations.TypedTuple typle:typedTuples){
            Map<String, Object> userRankMap = new HashMap<>();
            userRankMap.put("userId",typle.getValue());
            userRankMap.put("count",typle.getScore().intValue());
            userRankMap.put("rank",++index);
            String userInfo = redisTemplate.opsForValue().get(REDISKEY+ "_" + typle.getValue());
            if(StringUtils.isNotBlank(userInfo)){
                Map userInfoMap = JSON.parseObject(userInfo, HashMap.class);
                userRankMap.put("nickName",userInfoMap.get("nickName"));
                userRankMap.put("headImg",userInfoMap.get("headImg"));
            }
            rank.add(userRankMap);
        }
        return rank;
    }
/**
     * 功能描述 獲取 我的 排名信息
     * @author zm
     * @date 2019/9/23 10:42 
     * @param  userId
     * @return java.util.Map<java.lang.String,java.lang.Object>
     */
    private Map<String,Object> getUserRank(String userId){
        Long userRank = redisTemplate.opsForZSet().reverseRank(REDISKEY, userId);//我的排名
        Double count = redisTemplate.opsForZSet().score(REDISKEY, userId);//我的分數
        Map<String, Object> userRankMap = new HashMap<>();
        userRankMap.put("userId",userId);
        if(userRank ==null || agentCount ==null){
            return null;
        }
        userRankMap.put("count",count.intValue());
        userRankMap.put("rank",userRank+1);
        String userInfo = redisTemplate.opsForValue().get(REDISKEY+ "_" + userId);
        if(StringUtils.isNotBlank(userInfo)){
            Map userInfoMap = JSON.parseObject(userInfo, HashMap.class);
            userRankMap.put("nickName",userInfoMap.get("nickName"));
            userRankMap.put("headImg",userInfoMap.get("headImg"));
        }
        return userRankMap;
    }

是不是比寫sql簡單太多了!!
redis zset,一塊錢三個,嘿嘿!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章