1、引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2、配置application.properties
redis.host=127.0.0.1
redis.port=6379
redis.pass=
redis.database=0
redis.maxIdle=300
redis.maxWait=3000
3、junit测试
@SpringBootTest
class RankDemoApplicationTests {
@Autowired
private StringRedisTemplate redisTemplate;
//判断这个文章的set集合有没有这个用户id
public boolean sHasKey(String key, String userId) {//传入article:1 userId
try {
return redisTemplate.opsForSet().isMember(key, userId);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
//给排行榜的某个文章点赞数+delta
public void zIncrementScore(String key, String member, long delta) {//步长
//zrevrange rank 0 9 withscores
redisTemplate.opsForZSet().incrementScore(key, member, delta);
}
public long sAdd(String key, String values) {
return redisTemplate.opsForSet().add(key, values);
}
//一个用户要对一个文章点赞
public void addScore(String userId,String articleId){
//1、这个用户点赞过这篇文章吗?(不能取消点赞)
boolean flag=sHasKey("article:"+articleId,userId);
if (flag)
System.out.println("用户"+userId+"不能重复对文章"+articleId+"点赞");
//如果要取消点赞,那么就每次用户点赞之前判断一下set的这个文章是否有这个用户id,有就对这个文章点赞数-1,然后在set中这个文章中移出这个用户id
else{
//2、对该文章的点赞数+1 zincrby rank 1 article:1
zIncrementScore("rank","article:"+articleId,1);
//3、这个用户id加入这个文章的set
sAdd("article:"+articleId,userId);
System.out.println("用户"+userId+"点赞成功");
}
}
public Set<ZSetOperations.TypedTuple<String>> getZSetRank(String key, long start, long end) {
//zrevrange rank 0 9 withscores
Set<ZSetOperations.TypedTuple<String>> result= redisTemplate.opsForZSet().reverseRangeWithScores(key, start, end);
for (ZSetOperations.TypedTuple<String> s:result) {
System.out.println(s.getValue());//分割value,去拿到数组最后一个字符串元素,就是文章id,此时根据文章id去数据库查文章的其他信息,封装到list<ArticleVo>集合返回
System.out.println(s.getScore());
}
return result;
}
@Test
public void test(){
//用户对文章点赞
addScore("4","4");
//降序查询前十名(这个的话可以用定时任务每日更新一下)
getZSetRank("rank",0,9);
}
}
4、参考
Redis有序集合实现排行榜功能 - 林必昭的博客社区 - OSCHINA - 中文开源技术交流社区