SpringBoot继承Redis实现排行榜

项目文件结构

1、修改maven文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.4.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.wu</groupId><artifactId>rank</artifactId><version>0.0.1-SNAPSHOT</version><name>rank</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!--redis的依赖包--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.38</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

  

2、redis配置文件

spring.application.name=spring-boot-redis# 配置redis# Redis数据库索引(默认为0)
spring.redis.database=0
# Redis服务器地址
spring.redis.host=127.0.0.1
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=foobared
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.pool.max-active=8
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.pool.max-wait=-1
# 连接池中的最大空闲连接
spring.redis.pool.max-idle=8
# 连接池中的最小空闲连接
spring.redis.pool.min-idle=0
# 连接超时时间(毫秒)
spring.redis.timeout=200 # 这个地方需要

这里上面的redis的密码需要根据实际情况进行修改

3、RedisConfig文件

package com.wu.rank.config;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;@Configuration
public class RedisConfig {@Beanpublic RedisTemplate<String, String> redisTemplate(RedisConnectionFactory redisConnectionFactory) {StringRedisTemplate redis = new StringRedisTemplate();redis.setConnectionFactory(redisConnectionFactory);// 设置redis的String/value的默认序列化方式DefaultSerializer stringRedisSerializer = new DefaultSerializer();redis.setKeySerializer(stringRedisSerializer);redis.setValueSerializer(stringRedisSerializer);redis.setHashKeySerializer(stringRedisSerializer);redis.setHashValueSerializer(stringRedisSerializer);redis.afterPropertiesSet();return redis;}
}

  

4、DefaultSerializer文件

package com.wu.rank.config;import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import org.springframework.util.Assert;import java.nio.charset.Charset;public class DefaultSerializer implements RedisSerializer<Object> {private final Charset charset;public DefaultSerializer() {this(Charset.forName("UTF8"));}public DefaultSerializer(Charset charset) {Assert.notNull(charset, "Charset must not be null!");this.charset = charset;}@Overridepublic byte[] serialize(Object o) throws SerializationException {return o == null ? null : String.valueOf(o).getBytes(charset);}@Overridepublic Object deserialize(byte[] bytes) throws SerializationException {return bytes == null ? null : new String(bytes, charset);}
}

  

component文件夹

5、RedisComponent代码

package com.wu.rank.component;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Component;import java.util.Set;@Component
public class RedisComponent {@Autowiredprivate StringRedisTemplate redisTemplate;/*** 添加一个元素, zset与set最大的区别就是每个元素都有一个score,因此有个排序的辅助功能;  zadd** @param key* @param value* @param score*/public void add(String key, String value, double score) {redisTemplate.opsForZSet().add(key, value, score);}/*** 删除元素 zrem** @param key* @param value*/public void remove(String key, String value) {redisTemplate.opsForZSet().remove(key, value);}/*** score的增加or减少 zincrby** @param key* @param value* @param score*/public Double incrScore(String key, String value, double score) {return redisTemplate.opsForZSet().incrementScore(key, value, score);}/*** 查询value对应的score   zscore** @param key* @param value* @return*/public Double score(String key, String value) {return redisTemplate.opsForZSet().score(key, value);}/*** 判断value在zset中的排名  zrank** 积分小的在前面** @param key* @param value* @return*/public Long rank(String key, String value) {return redisTemplate.opsForZSet().rank(key, value);}/*** 查询集合中指定顺序的值, 0 -1 表示获取全部的集合内容  zrange** 返回有序的集合,score小的在前面** @param key* @param start* @param end* @return*/public Set<String> range(String key, long start, long end) {return redisTemplate.opsForZSet().range(key, start, end);}/*** 查询集合中指定顺序的值和score,0, -1 表示获取全部的集合内容** @param key* @param start* @param end* @return*/public Set<ZSetOperations.TypedTuple<String>> rangeWithScore(String key, long start, long end) {return redisTemplate.opsForZSet().rangeWithScores(key, start, end);}/*** 查询集合中指定顺序的值  zrevrange** 返回有序的集合中,score大的在前面** @param key* @param start* @param end* @return*/public Set<String> revRange(String key, long start, long end) {return redisTemplate.opsForZSet().reverseRange(key, start, end);}/*** 根据score的值,来获取满足条件的集合  zrangebyscore** @param key* @param min* @param max* @return*/public Set<String> sortRange(String key, long min, long max) {return redisTemplate.opsForZSet().rangeByScore(key, min, max);}/*** 返回集合的长度** @param key* @return*/public Long size(String key) {return redisTemplate.opsForZSet().zCard(key);}}

  

6、RankListComponent

package com.wu.rank.component;import com.wu.rank.model.RankDO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Component;import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;@Component
public class RankListComponent {@Autowiredprivate RedisComponent redisComponent;private static final String RANK_PREFIX = "global_rank";private List<RankDO> buildRedisRankToBizDO(Set<ZSetOperations.TypedTuple<String>> result, long offset) {List<RankDO> rankList = new ArrayList<>(result.size());long rank = offset;for (ZSetOperations.TypedTuple<String> sub : result) {rankList.add(new RankDO(rank++, Math.abs(sub.getScore().floatValue()), Long.parseLong(sub.getValue())));}return rankList;}/*** 获取前n名的排行榜数据** @param n* @return*/public List<RankDO> getTopNRanks(int n) {Set<ZSetOperations.TypedTuple<String>> result = redisComponent.rangeWithScore(RANK_PREFIX, 0, n - 1);return buildRedisRankToBizDO(result, 1);}/*** 获取用户所在排行榜的位置,以及排行榜中其前后n个用户的排行信息** @param userId* @param n* @return*/public List<RankDO> getRankAroundUser(Long userId, int n) {// 首先是获取用户对应的排名RankDO rank = getRank(userId);if (rank.getRank() <= 0) {// fixme 用户没有上榜时,不返回return Collections.emptyList();}// 因为实际的排名是从0开始的,所以查询周边排名时,需要将n-1Set<ZSetOperations.TypedTuple<String>> result =redisComponent.rangeWithScore(RANK_PREFIX, Math.max(0, rank.getRank() - n - 1), rank.getRank() + n - 1);return buildRedisRankToBizDO(result, rank.getRank() - n);}/*** 获取用户的排行榜位置** @param userId* @return*/public RankDO getRank(Long userId) {// 获取排行, 因为默认是0为开头,因此实际的排名需要+1Long rank = redisComponent.rank(RANK_PREFIX, String.valueOf(userId));if (rank == null) {// 没有排行时,直接返回一个默认的return new RankDO(-1L, 0F, userId);}// 获取积分Double score = redisComponent.score(RANK_PREFIX, String.valueOf(userId));return new RankDO(rank + 1, Math.abs(score.floatValue()), userId);}/*** 更新用户积分,并获取最新的个人所在排行榜信息** @param userId* @param score* @return*/public RankDO updateRank(Long userId, Float score) {// 因为zset默认积分小的在前面,所以我们对score进行取反,这样用户的积分越大,对应的score越小,排名越高redisComponent.add(RANK_PREFIX, String.valueOf(userId), -score);Long rank = redisComponent.rank(RANK_PREFIX, String.valueOf(userId));return new RankDO(rank + 1, score, userId);}}

  

Model文件夹

7、RankDO

package com.wu.rank.model;import java.io.Serializable;public class RankDO implements Serializable {private static final long serialVersionUID = 4804922606006935590L;/*** 排名*/private Long rank;/*** 积分*/private Float score;/*** 用户id*/private Long userId;public RankDO(Long rank, Float score, Long userId) {this.rank = rank;this.score = score;this.userId = userId;}public static long getSerialVersionUID() {return serialVersionUID;}public Long getRank() {return rank;}public void setRank(Long rank) {this.rank = rank;}public Float getScore() {return score;}public void setScore(Float score) {this.score = score;}public Long getUserId() {return userId;}public void setUserId(Long userId) {this.userId = userId;}
}

  

8、controller文件夹

RankAction

package com.wu.rank.controller;import com.wu.rank.component.RankListComponent;
import com.wu.rank.model.RankDO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.List;@RestController
public class RankAction {@Autowiredprivate RankListComponent rankListComponent;@GetMapping(path = "/topn")public List<RankDO> showTopN(int n) {return rankListComponent.getTopNRanks(n);}@GetMapping(path = "/update")public RankDO updateScore(long userId, float score) {return rankListComponent.updateRank(userId, score);}@GetMapping(path = "/rank")public RankDO queryRank(long userId) {return rankListComponent.getRank(userId);}@GetMapping(path = "/around")public List<RankDO> around(long userId, int n) {return rankListComponent.getRankAroundUser(userId, n);}}

  

主程序代码

package com.wu.rank;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class RankApplication {public static void main(String[] args) {SpringApplication.run(RankApplication.class, args);}}

  

测试

1、先运行redis服务器

2、打开postman进行测试

参考:

1、https://github.com/liuyueyi/spring-boot-demo/tree/master/spring-case/120-redis-ranklist

转载于:https://www.cnblogs.com/wylwyl/p/10819447.html

SpringBoot集成Redis实现排行榜相关推荐

  1. redis 依赖_springboot|springboot集成redis缓存

    javaDEMO 本网站记录了最全的各种JavaDEMO ,保证下载,复制就是可用的,包括基础的, 集合的, spring的, Mybatis的等等各种,助力你从菜鸟到大牛,记得收藏哦~~https: ...

  2. SpringBoot集成Redis用法笔记

    今天给大家整理一下SpringBoot集成Redis用法笔记,希望对大家能有所帮助! 一.Redis优点介绍 1.速度快 不需要等待磁盘的IO,在内存之间进行的数据存储和查询,速度非常快.当然,缓存的 ...

  3. springboot集成redis使用redis作为session报错ClassNotFoundException类RememberMeServices

    springboot 集成redis使用redis作为缓存,会报错的问题. 错误信息: java.lang.IllegalStateException: Error processing condit ...

  4. SpringBoot集成Redis缓存

    SpringBoot集成Redis缓存 前言 本系列文章将简单的学习SpringCloud微服务相关知识,其实也是因为时间的原因,一直拖到现在,遂打算趁着假期,决定记录下来. 从天气预报微服务系统的单 ...

  5. 关于springboot集成redis及关于redis的Key 乱码问题

    一.在pom文件中引入redis <dependency><groupId>org.springframework.boot</groupId><artifa ...

  6. springboot 集成redis key乱码\xac\xed\x00\x05t\x00\x0eHAOKE_HOT_WORD

    文章目录 场景 分析 解决 场景 springboot集成redis集群 检查key时发现key是二进制格式的 \xac\xed\x00\x05t\x00\x0eHAOKE_HOT_WORD 分析 R ...

  7. SpringBoot集成Redis笔记-动力节点王鹤

    关于springboot集成redis,我做了笔记,分享给小伙伴们,视频看的动力节点王鹤老师讲的, 动力节点王鹤老师讲解的springboot教程,由浅入深,带你体验Spring Boot的极速开发过 ...

  8. SpringBoot集成Redis并使用Knife4j测试

    SpringBoot集成Redis并使用Knife4j测试 基于若依的ruoyi-vue前后端分离版本,若依官网:http://www.ruoyi.vip/ 项目目录结构 项目的目录结构如下: 1.新 ...

  9. Redis第三话 – Springboot集成Redis以及常用API和客户端介绍

    本文主要记录在Springboot中集成Redis的使用. 1. springboot集成redis 1.1 maven配置 基于springboot 版本2.5.6,parent包就不贴了. < ...

最新文章

  1. php5.3.6安装教程,apache2.2.19+php5.3.6配置教程
  2. codeforces597c[树状数组+dp]
  3. 利用Travis CI 让你的github项目持续构建(Node.js为例)
  4. 求素数——多线程练习
  5. C语言数据结构各种排序算法(选择,直接,希尔,起泡等排序)
  6. MySQL的InnoDB表如何设计主键索引-转自淘宝MySQL经典案例
  7. Security+ 学习笔记45 移动设备安全
  8. UNITY游戏制作流程
  9. 用envi对遥感影像进行规则裁剪
  10. MongoDB 清理数据
  11. 如何向下属布置工作任务,5个步骤,布置工作任务更清晰
  12. Fedora20在神州战神K650D1安装过程,使用netinstall和Dvd.iso镜像安装。
  13. 爱奇艺发布年报:四季度运营大幅减亏,今年提质增效追盈利
  14. security update 补丁更新失败
  15. ArduinoProteus 8 Professional——(超声波检测传感器SRF04(距离检测))for Neuedu
  16. 设计模式笔记-----七大原则
  17. Source Insight——C/C++代码阅读器
  18. 一个很好的看电子书的软件
  19. 【基本办公软件】万彩办公大师教程丨高级计算器的应用
  20. 2019年全国电子设计大赛综合测评感悟

热门文章

  1. MyBatis的入门知识
  2. jquery返回顶部
  3. Oralce 数据库 - 查询数据库所有的表和视图实例演示,查询指定用户下所有表和视图方法
  4. CTFshow php特性 web107
  5. c语言或者cpp中位运算的技巧
  6. 【Kaggle-MNIST之路】CNN+改进过的损失函数+多次的epoch(四)
  7. 用python做数据分析,安装包一次到位
  8. 2.3.3 Softmax回归介绍
  9. html函数中怎么写超链接,如何调用html超链接中的函数
  10. 利用keepalived和haproxy配置mysql的高可用负载均衡