一般排行榜信息 = 用户信息(头像-昵称) + 用户成绩(分数-排名)组成
因此我们可以使用 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;
}
文章描述了一个使用Redis数据存储用户信息和成绩,并通过ZSet实现排行榜功能的系统。通过ZAdd方法存储用户分数,利用ZSet的排序特性获取排行榜,同时Hash结构存储用户详细信息,当需要时从数据库更新缓存。
1609

被折叠的 条评论
为什么被折叠?



