当前位置: 首页 > news >正文

重学SpringBoot3-集成Redis(十三)之点排行榜实现

更多SpringBoot3内容请关注我的专栏:《SpringBoot3》
期待您的点赞👍收藏⭐评论✍

重学SpringBoot3-集成Redis(十三)之点排行榜实现

  • 1. 为什么选择 Redis 来实现排行榜?
  • 2. 项目环境准备
      • 2.1. 添加依赖
      • 2.2. 配置 Redis 连接
  • 3. 排行榜功能实现
    • 3.1 排行榜服务的实现
    • 3.2 排行榜功能的 REST 接口
    • 3.3 测试接口
  • 4. 关键代码解析
  • 5. 小结

在现代应用程序中,排行榜功能常用于展示用户或内容的排名,如游戏中的分数排名、社交平台上的活跃度排名等。Redis 提供的有序集合(Sorted Set)结构,能够通过分数进行排序,非常适合用来构建排行榜。本文将介绍如何使用 Spring Boot 3Redis 实现一个简单的排行榜功能。

1. 为什么选择 Redis 来实现排行榜?

Redis 的有序集合(Sorted Set)具备以下优点:

  • 高效排序:有序集合是通过分数(Score)来进行排序的,支持快速的插入、删除和排序操作。
  • 高性能:Redis 是内存数据库,读写速度非常快,特别适合实时性要求高的应用。
  • 丰富的操作:Redis 提供了多种操作命令,如按分数范围查询、获取前 N 名等,非常适合排行榜的需求。

Redis 有序集合通过 zadd 命令向集合中添加成员,并为每个成员设置一个分数。通过 zrange 等命令可以按分数从小到大或从大到小获取成员的排名。

排行榜举例

2. 项目环境准备

2.1. 添加依赖

首先,在 pom.xml 中引入 Spring Boot 3Redis 的相关依赖,具体参考重学SpringBoot3-集成Redis(一)之基本使用:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>

2.2. 配置 Redis 连接

application.yml 中配置 Redis:

spring:data:redis:host: localhostport: 6379            # Redis 端口password: redis123456 # 如果有密码可以在这里配置lettuce:pool:max-active: 100    # 最大并发连接数max-idle: 50       # 最大空闲连接数min-idle: 10       # 最小空闲连接数

3. 排行榜功能实现

3.1 排行榜服务的实现

我们使用 Redis 的有序集合(Sorted Set)来存储排行榜的数据。成员(用户或内容)作为集合的元素,得分(如游戏分数、点赞数)作为排序依据。

package com.coderjia.boot310redis.service;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;import java.util.HashMap;
import java.util.Map;
import java.util.Set;/*** @author CoderJia* @create 2024/10/7 下午 09:13* @Description**/
@Service
public class LeaderboardService {@Autowiredprivate StringRedisTemplate redisTemplate;private static final String LEADERBOARD_KEY = "leaderboard";// 添加用户及其得分到排行榜public void addUserToLeaderboard(String userId, double score) {redisTemplate.opsForZSet().add(LEADERBOARD_KEY, userId, score);}// 获取前N名用户public Set<String> getTopUsers(int n) {return redisTemplate.opsForZSet().reverseRange(LEADERBOARD_KEY, 0, n - 1);}// 获取某个用户的排名public Long getUserRank(String userId) {return redisTemplate.opsForZSet().reverseRank(LEADERBOARD_KEY, userId);}// 获取某个用户的得分public Double getUserScore(String userId) {return redisTemplate.opsForZSet().score(LEADERBOARD_KEY, userId);}// 获取用户的排名和得分public Map<String, Object> getUserRankAndScore(String userId) {Map<String, Object> result = new HashMap<>();result.put("rank", getUserRank(userId));result.put("score", getUserScore(userId));return result;}
}

3.2 排行榜功能的 REST 接口

为排行榜功能创建简单的 REST API,用户可以通过该接口添加分数、查看前几名和用户排名等操作。

package com.coderjia.boot310redis.demos.web;import com.coderjia.boot310redis.service.LeaderboardService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import java.util.Map;
import java.util.Set;/*** @author CoderJia* @create 2024/10/10 下午 10:36* @Description**/
@RestController
@RequestMapping("/api/leaderboard")
public class LeaderboardController {@Autowiredprivate LeaderboardService leaderboardService;// 添加用户得分@PostMapping("/add")public ResponseEntity<String> addUser(@RequestParam("userId") String userId, @RequestParam("score") double score) {leaderboardService.addUserToLeaderboard(userId, score);return ResponseEntity.ok("User added to leaderboard.");}// 获取前N名@GetMapping("/top")public ResponseEntity<Set<String>> getTopUsers(@RequestParam("topN") int topN) {return ResponseEntity.ok(leaderboardService.getTopUsers(topN));}// 获取某个用户的排名和得分@GetMapping("/user/{userId}")public ResponseEntity<Map<String, Object>> getUserRankAndScore(@PathVariable String userId) {return ResponseEntity.ok(leaderboardService.getUserRankAndScore(userId));}
}

3.3 测试接口

你可以使用 Postman 或 curl 来测试这些接口。例如,添加用户的接口请求可以这样发起:

curl -X POST "http://localhost:8080/api/leaderboard/add?userId=1&score=100"

添加用户

获取前 5 名的接口请求:

curl -X GET "http://localhost:8080/api/leaderboard/top?topN=5"

Top5

获取某个用户的排名和得分:

curl -X GET "http://localhost:8080/api/leaderboard/user/1"

获取某个用户的排名

4. 关键代码解析

  • redisTemplate.opsForZSet().add(key, value, score):将用户 ID 和分数作为一对数据添加到有序集合中,key 为排行榜的键。
  • redisTemplate.opsForZSet().reverseRange(key, start, end):根据分数从高到低获取排行榜前几名用户。
  • redisTemplate.opsForZSet().reverseRank(key, value):获取用户的排名,返回值是排名(从 0 开始)。
  • redisTemplate.opsForZSet().score(key, value):获取用户的分数。

5. 小结

使用 Spring Boot 3Redis 实现排行榜非常高效且简便。Redis 的有序集合为我们提供了强大的排序功能,能够轻松处理各种排行榜需求。通过该方案,我们可以实现以下功能:

  • 动态添加用户得分到排行榜
  • 实时获取前几名的用户
  • 查询用户的排名和分数

Redis 由于其快速的读写性能,非常适合用于实时性要求高的排行榜应用场景。如果你需要开发类似的功能,Redis 无疑是一个理想的选择。

相关文章:

重学SpringBoot3-集成Redis(十三)之点排行榜实现

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 重学SpringBoot3-集成Redis&#xff08;十三&#xff09;之点排行榜实现 1. 为什么选择 Redis 来实现排行榜&#xff1f;2. 项目环境准备2.1. 添加依赖2.2. 配置 Redis 连…...

Java 中方法参数传递的陷阱

前言 在编程过程中&#xff0c;我们经常会遇到一些看似简单却容易出错的问题。本文将通过一个具体的例子&#xff0c;探讨 Java 中方法参数传递的陷阱&#xff0c;并提供详细的解决方法。希望这篇文章能帮助你在未来的开发中避免类似的错误。 问题背景 假设我们的任务是计算…...

哪家云电脑便宜又好用?ToDesk云电脑、顺网云、达龙云全方位评测

陈老老老板&#x1f934; &#x1f9d9;‍♂️本文专栏&#xff1a;生活&#xff08;主要讲一下自己生活相关的内容&#xff09;生活就像海洋,只有意志坚强的人,才能到达彼岸。 &#x1f9d9;‍♂️本文简述&#xff1a;讲一下市面上云电脑的对比。 &#x1f9d9;‍♂️上一篇文…...

【汇编语言】寄存器(内存访问)(三)—— 字的传送

文章目录 前言1. 字的传送2. 问题一3. 问题一的分析与解答4. 问题二5. 问题二的分析与解答结语 前言 &#x1f4cc; 汇编语言是很多相关课程&#xff08;如数据结构、操作系统、微机原理&#xff09;的重要基础。但仅仅从课程的角度出发就太片面了&#xff0c;其实学习汇编语言…...

6 机器学习之应用现状

在过去二十年中&#xff0c;人类收集、存储、传输、处理数据的能力取得了飞速提升&#xff0c;人类社会的各个角落都积累了大量数据&#xff0c;亟需能有效地对数据进行分析利用的计算机算法&#xff0c;而机器学习恰顺应了大时代的这个迫切需求&#xff0c;因此该学科领域很自…...

相似度为 K 的字符串

题目链接 相似度为 K 的字符串 题目描述 注意 s1和s2只包含集合 {‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’} 中的小写字母s2是s1的一个字母异位词 解答思路 可以深度优先遍历交换字母使得s1和s2尽可能接近&#xff0c;基本思路是&#xff1a;设定一个指针idx指向s1和s2的…...

[云] Project Analysis

项目要求分析&#xff1a; 开放性选题&#xff1a; 主题范围&#xff1a;任何与云计算系统相关的主题。项目类型&#xff1a;可以是技术、商业或研究项目。团队规模&#xff1a;最多可组成三人小组。 示例主题&#xff1a; 分析公共云数据&#xff1a;例如&#xff0c;AWS公共数…...

腾讯六宫格本地识别,本地模型识别,腾讯六图识别

基于K哥爬虫昨天发的文章&#xff0c;特此训练了一版腾讯模型&#xff0c;效果不错&#xff0c;特此感谢K哥的指导&#xff0c;效果如下图: 有需求&#xff0c;有疑问的欢迎评论区点出...

Transformer图解以及相关的概念

前言 transformer是目前NLP甚至是整个深度学习领域不能不提到的框架&#xff0c;同时大部分LLM也是使用其进行训练生成模型&#xff0c;所以transformer几乎是目前每一个机器人开发者或者人工智能开发者不能越过的一个框架。接下来本文将从顶层往下去一步步掀开transformer的面…...

Nginx缓存静态文件

在Python项目中&#xff0c;通过Nginx缓存静态文件&#xff08;如CSS、JS、图片等&#xff09;&#xff0c;可以有效提升网页的加载性能。Nginx可以帮助你缓存静态资源&#xff0c;减少服务器负担&#xff0c;并加速页面加载。 1. 配置Nginx缓存静态文件 首先&#xff0c;你需…...

【隐私计算】隐语HEU同态加密算法解读

HEU: 一个高性能的同态加密算法库&#xff0c;提供了多种 PHE 算法&#xff0c; 包括ZPaillier、FPaillier、IPCL、Damgard Jurik、DGK、OU、EC ElGamal 以及基于FPGA和GPU硬件加速版本的Paillier版本。 本文我们会基于GPU运行HEU Docker容器&#xff0c;编译打包GPaillier并测…...

用C#实现互斥操作

1、传统的lock lock简单易用&#xff0c;适合大多数场景&#xff0c;但在高竞争用情况下可能会导致线程阻塞&#xff1b; Object obj new object(); void method1(){lock (obj){// 进行互斥操作}}2、SpinLock SpinLock在低延迟情况下更有效&#xff0c;因为SpinLock会在忙等…...

【黑马点评优化】之使用Caffeine+Redis实现应用级二层缓存

【黑马点评优化】之使用CaffeineRedis实现应用级二层缓存 1 缓存雪崩定义及解决方案2 为什么要使用多级缓存3 RedisCaffeine实现应用层二级缓存原理4 利用CaffeineRedis解决Redis突然宕机导致的缓存雪崩问题4.1 pom.xml文件引入相关依赖4.2 本地缓存配置类4.3 修改ShopServiceI…...

CEEMDAN +组合预测模型(BiLSTM-Attention + ARIMA)

往期精彩内容&#xff1a; 时序预测&#xff1a;LSTM、ARIMA、Holt-Winters、SARIMA模型的分析与比较 全是干货 | 数据集、学习资料、建模资源分享&#xff01; EMD、EEMD、FEEMD、CEEMD、CEEMDAN的区别、原理和Python实现&#xff08;一&#xff09;EMD-CSDN博客 EMD、EEM…...

2.1.ReactOS系统中断描述符的格式KIDTENTRY结构体

2.&#xff11;.ReactOS系统中断描述符的格式KIDTENTRY结构体 2.&#xff11;.ReactOS系统中断描述符的格式KIDTENTRY结构体 文章目录 2.&#xff11;.ReactOS系统中断描述符的格式KIDTENTRY结构体KIDTENTRY KIDTENTRY 数据结构KIDTENTRY定义了CPU对中断描述符的格式 // // …...

三、ElementPlus下拉搜索加弹窗组件的封装

近期产品提出了一个需求&#xff0c;要求一个form的表单里面的一个组件既可以下拉模糊搜索&#xff0c;又可以弹窗搜索&#xff0c;我就为这个封装了一个组件&#xff0c;下面看效果图。 效果大家看到了&#xff0c;下面就看组件封装和实现方法 第一步&#xff0c;组件封装&…...

androidStudio编译导致的同名.so文件冲突问题解决

files found with path lib/arm64-v8a/libserial_port.so from inputs: ...\build\intermediates\library_jni\debug\jni\arm64-v8a\libserial_port.so C:\Users\...\.gradle\caches\transforms-3\...\jni\arm64-v8a\XXX.so 解决方式如下&#xff1a; 1.将gradle缓存文件删…...

大学新生编程入门指南:如何选择编程语言与制定学习计划

大学新生编程入门指南&#xff1a;如何选择编程语言与制定学习计划 编程已成为当代大学生的必备技能&#xff0c;尤其是在信息技术高速发展的今天&#xff0c;编程能力不仅能帮助你在课堂学习中脱颖而出&#xff0c;更能为未来职业生涯打下坚实的基础。然而&#xff0c;面对如…...

SpringAI快速上手

一、导入依赖 镜像&#xff08;导入maven依赖&#xff09; <repositories><repository><id>spring-snapshots</id><name>Spring Snapshots</name><url>https://repo.spring.io/snapshot</url><releases><enabled>…...

07 django管理系统 - 部门管理 - 搜索部门

在dept_list.html中&#xff0c;添加搜索框 <div class"container-fluid"><div style"margin-bottom: 10px" class"clearfix"><div class"panel panel-default"><!-- Default panel contents --><div clas…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

Cursor实现用excel数据填充word模版的方法

cursor主页&#xff1a;https://www.cursor.com/ 任务目标&#xff1a;把excel格式的数据里的单元格&#xff0c;按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例&#xff0c;…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

微信小程序 - 手机震动

一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注&#xff1a;文档 https://developers.weixin.qq…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

HBuilderX安装(uni-app和小程序开发)

下载HBuilderX 访问官方网站&#xff1a;https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本&#xff1a; Windows版&#xff08;推荐下载标准版&#xff09; Windows系统安装步骤 运行安装程序&#xff1a; 双击下载的.exe安装文件 如果出现安全提示&…...

汇编常见指令

汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX&#xff08;不访问内存&#xff09;XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...