Java应用redis的zset实现排行榜功能

844 阅读2分钟

在工作中,有时候需要实现排行榜功能。如果直接使用数据库记录数据,会增加服务器的压力。这时,可以考虑使用 Redis 的 zset(有序集合)功能来实现排行榜,以减轻数据库压力。

封装 Redis 工具类的实现方法

下面是一些常用的 zset 操作方法,都封装在一个 Redis 工具类中。

1. 存入单条数据

如果当前 key 里的数据存在,会覆盖之前的数据;不存在则新增一条;返回是否存储成功。

public static boolean zsetAdd(final String key, final String values, double score) {
  return Boolean.TRUE.equals(redisTemplate.opsForZSet().add(key, values, score));
}

2. 存入数据列表

新增一组数据;如果新增的数据里有已存在的,则会覆盖之前的数据;返回存入的条数。

public static long zsetSet(final String key, final Set<ZSetOperations.TypedTuple<String>> values) {
  Long count = redisTemplate.opsForZSet().add(key, values);
  return count == null ? 0 : count;
}

3. 修改数据

对数据原有的值累加(参数为负数则为减);数据不存在则新增;返回修改后的值。

public static Double zsetEdit(final String key, final String values, double score) {
  return redisTemplate.opsForZSet().incrementScore(key, values, score);
}

4. 删除数据

返回删除的条数。

public static Long zsetDel(final String key, final String values) {
  Long count = redisTemplate.opsForZSet().remove(key, values);
  return count == null ? 0 : count;
}

5. 获取单条数据

返回该数据的值,不存在则返回null。

public static Double getZsetByValue(final String key, final String value) {
  return redisTemplate.opsForZSet().score(key, value);
}

返回键值对的形式,不存在返回0。

public static ZSetOperations.TypedTuple<String> getZsetByValue(final String key, final String value) {
  if (redisTemplate.opsForZSet().rank(key, value) == null) {
      return null;
  }
  Long index = redisTemplate.opsForZSet().rank(key, value);
  Set<ZSetOperations.TypedTuple<String>> typedTupleSet = redisTemplate.opsForZSet().rangeWithScores(key, index, index);
  return typedTupleSet != null ? typedTupleSet.iterator().next() : new DefaultTypedTuple(value, 0.0);
}

6. 获取记录的大小

public static Long getZsetSize(final String key) {
    return redisTemplate.opsForZSet().size(key);
}

7. 根据下标获取数据列表

public static Set<ZSetOperations.TypedTuple<String>> getZsetSetDesc(final String key, final long start, final long end) {
  return redisTemplate.opsForZSet().reverseRangeWithScores(key, start, end);
}

具体应用

1. 分页获取数据列表

可以通过传入页码和每页条目数来获取分页数据。下面是一个示例代码:

public Set<ZSetOperations.TypedTuple<String>> getQuestionRankIdsByPage(long current, long size) {
  long start = (current - 1) * size;
  long end = (current * size) - 1;
  Set<ZSetOperations.TypedTuple<String>> typedTuples = RedisUtils.getZsetSetDesc(RedisKeyEnum.QUESTION_RANK_IDS.getCode(), start, end);
  return typedTuples;
}

这个方法使用了 RedisUtils 工具类中的 getZsetSetDesc() 方法,它会返回一个 Set<ZSetOperations.TypedTuple> 类型的对象,该对象包含了指定范围内的排行数据。通过传入的 current 和 size 参数来计算出数据的起始下标和结束下标,然后调用 getZsetSetDesc() 方法来获取对应的数

以上是本篇文章的全部内容。 只是个人在工作中应用到的技术做记录和分享,仅供参考。