一般排行榜信息 = 用户信息(头像-昵称) + 用户成绩(分数-排名)组成
因此我们可以使用 hash 这一数据结构存储用户信息,使用zset 这一数据结构存储用户成绩 。
// 用户成绩储存
SyncRedisUtils syncRedisUtils = new SyncRedisUtils(redisUtils);
syncRedisUtils.SyncRedis("light_game", Integer.valueOf(identity),lightGameSaveVO.getCoinTotal());
public class SyncRedisUtils { private RedisUtils redisUtils; public SyncRedisUtils(RedisUtils redisUtils) { this.redisUtils = redisUtils; } /** * 插入分数,根据分数和当前时间比较 */ 因为公司用户在国外,所以选取的是美国时区 public void SyncRedis(String key, Integer accountId, Integer value) { LocalDateTime nowTime = LocalDateTime.now(TimeZone.getTimeZone("America/Los_Angeles").toZoneId()); long second = 9999999999L - nowTime.toInstant(ZoneOffset.of("-8")).toEpochMilli() / 1000; String dou = value + "." + second + ""; double newCount = Double.parseDouble(dou); redisUtils.zAdd(key,accountId,newCount); } } // 用户信息储存
User user = userMapper.getUser(identity); redisUtils.hset("light_game_user",identity,user); // 存入hash 现在已经完成信息存储了,就要考虑实现排行榜了,下面是实现代码
//排行榜 List<RightGameRankVO.RankListVO> rankListVOS = new ArrayList<>(); Set<Object> reverseRange = redisUtils.reverseRange("light_game",0,49); Map<String,Double> scoreMap = redisUtils.getZSetMembersAndScores("light_game",0,49); if (reverseRange != null && reverseRange.size() > 0) { List<Object> reverseRangeList = new ArrayList<>(reverseRange); List<String> accountIdList = reverseRangeList.stream().map(String::valueOf).collect(Collectors.toList()); for(String accountId : accountIdList){ RightGameRankVO.RankListVO rankListDTO = new RightGameRankVO.RankListVO(); User userOne = (User) redisUtils.hget("light_game_user",accountId); if(userOne == null){ // 更新缓存 userOne = userMapper.getUserByAccountId(accountId); redisUtils.hset("light_game_user",accountId,userOne); } rankListDTO.setRanking(RANK); Double coinTotal = scoreMap.get(accountId); rankListDTO.setCoinTotal((int) Math.floor(coinTotal)); rankListDTO.setHeadPortrait(userOne.getHeadPortrait()); rankListDTO.setNickName(userOne.getNickName()); rankListVOS.add(rankListDTO); RANK++; } }
public void zAdd(String key, Object accountId, Object value) { redisTemplate.opsForZSet().add(key, accountId, (Double) value); } /** * 获取用户排序 * @param key 键 * @param value 值 * @return */ public Long reverseRank(String key, Object value) { Long userRank = redisTemplate.opsForZSet().reverseRank(key, value); return userRank; } /** * 获取范围排序 * @param key 键 * @return */ public Set<Object> reverseRange(String key, int start, int end) { Set<Object> reverseRange = redisTemplate.opsForZSet().reverseRange(key, start, end); return reverseRange; }
// 可根据 你的需要封装
public Map<String,Double> getZSetMembersAndScores(String key,int start, int end) { ZSetOperations<String, Object> zSetOps = redisTemplate.opsForZSet(); Map<String,Double> hash = new HashMap<>(); Set<ZSetOperations.TypedTuple<Object>> zSetMembersAndScores =zSetOps.reverseRangeWithScores(key, start, end); for (ZSetOperations.TypedTuple<Object> tuple : zSetMembersAndScores) { String member = String.valueOf(tuple.getValue()); Double score = tuple.getScore(); hash.put(member,score); } return hash; }