可以充值的网站怎么做,世界500强企业排行榜,js代码能用在wordpress吗,北京住房与建设部网站首页目录
一、排行榜的应用场景
二、排行榜技术的特点
三、使用Redis ZSET实现排行榜
3.1 引入依赖
3.2 配置Redis连接
3.3 创建实体类#xff08;可选#xff09;
3.4 编写 Redis 操作服务层
3.5 编写控制器层
3.6 测试
3.6.1 测试 addMovieScore 接口
3.6.2 测试 g…目录
一、排行榜的应用场景
二、排行榜技术的特点
三、使用Redis ZSET实现排行榜
3.1 引入依赖
3.2 配置Redis连接
3.3 创建实体类可选
3.4 编写 Redis 操作服务层
3.5 编写控制器层
3.6 测试
3.6.1 测试 addMovieScore 接口
3.6.2 测试 getTopNRankings 接口
3.6.3 测试 getMovieRank接口
3.6.4 测试 getMovieScore接口
前端测试代码 一、排行榜的应用场景 排行榜服务是一个看似简单但又复杂的设计其在互联网产品中应用非常广泛
游戏排行榜商品排行榜视频排行榜社交排行榜
互联网应用提供排行榜功能可以对关键信息起到增强曝光的作用并且可以在一定程度上提供用户的活跃度、参与度从而促进互联网产品的发展。 二、排行榜技术的特点 与现实生活中的排行榜不同互联网应用中的排行榜一般具有如下特点。
曝光量大竞争激烈实时变化周期滚动
所以在排行榜的技术实现方面要重点考虑高并发读/写、实时展示最新排名以及可以轻松支持周期滚动的能力。
在设计排行榜服务时首先要考虑的问题是使用什么存储系统来维护排行榜。假如使用关系型数据库的话因为它对高并发读/写的支持较弱面且为了支持按照评分排序在关系型数据库中需要根据分数/积分字段使用SELECT语句的ORDER BY子句来实现。而该方式具有如下缺点。
性能开销在有大量数据的情况下排序操作会耗费大量的系统资源和处理时间尤其是当需要进行多字段排序或者排序字段的数据类型不同时查询效率更低。磁盘I/O当需要对大量数据进行排序时可能要使用临时表或者磁盘存储技术使排序操作不再全部运行在内存中而这需要进行大量的磁盘读/写操作从面导致性能降低查询的响应时间变长。
所以实现排行榜不太适合使用关系型数据库。排行榜是按照积分排序的因此很容易让人想到Redis的ZSET数据结构。ZSET是一种有序集合形式该集合由Member组成每个Member都有一个Score(积分)集合会按照Score自动排序。所以目前Redis ZSET便成为实现排行榜的首选。 补充ZSET底层数据结构是通过压缩列表和跳表实现的 三、使用Redis ZSET实现排行榜
3.1 引入依赖
dependencygroupIdredis.clients/groupIdartifactIdjedis/artifactIdversion3.7.0/version !-- 使用合适的版本 --
/dependency 关于 Redis 客户端库 — Jedis : 在 Java 项目中如果需要通过代码去连接 Redis 数据库、执行如设置键值对、获取数据、进行列表操作、发布订阅等各种 Redis 支持的操作时就需要引入 Jedis 库。 这段依赖配置就是为了方便在 Java 项目中引入 Jedis 这个强大的 Redis 客户端库从而能在代码层面和 Redis 数据库进行交互操作实现各种基于 Redis 存储和缓存等功能需求。 3.2 配置Redis连接
在 application.yml文件中配置 Redis 连接信息 redis:host: localhost # 修改为实际Redis主机地址port: 6379 # 修改为实际Redis端口password: 123 # 修改为实际Redis密码database: 0 # 选择使用的数据库默认为0
3.3 创建实体类可选
这一步根据业务需求选择如果需要存储更复杂的电影相关信息用于排行榜可以创建对应的实体类这里简单以电影 ID 和评分为例
Data
Component
AllArgsConstructor
NoArgsConstructor
public class MovieScore {private String movieId;private double rating;
} 关于Lombok的安装和使用请参考(在文章末尾) Spring框架学习 有这一篇就够_spring 学习-CSDN博客 3.4 编写 Redis 操作服务层
package com.snut.selltickets.service;import com.snut.selltickets.model.MovieScore;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;import javax.annotation.Resource;
import java.util.Set;
import java.util.stream.Collectors;Service
public class RankService {private static final String RANKING_KEY movie_ranking;Resourceprivate RedisTemplateString, String redisTemplate;// 添加电影评分到排行榜public void addMovieScore(String movieId, double rating) {ZSetOperationsString, String zSetOperations redisTemplate.opsForZSet();zSetOperations.add(RANKING_KEY, movieId, rating);}// 获取排行榜前N名的电影这里返回电影ID和对应评分public SetMovieScore getTopNRankings(int n) {ZSetOperationsString, String zSetOperations redisTemplate.opsForZSet();return zSetOperations.reverseRangeWithScores(RANKING_KEY, 0, n - 1).stream().map(tuple - new MovieScore(tuple.getValue(), tuple.getScore())).collect(Collectors.toSet());}// 获取电影在排行榜中的排名从高到低排序排名从0开始public Long getMovieRank(String movieId) {ZSetOperationsString, String zSetOperations redisTemplate.opsForZSet();return zSetOperations.reverseRank(RANKING_KEY, movieId);}// 获取电影的评分public Double getMovieScore(String movieId) {ZSetOperationsString, String zSetOperations redisTemplate.opsForZSet();return zSetOperations.score(RANKING_KEY, movieId);}}3.5 编写控制器层
用于对外提供接口可测试调用
import com.snut.selltickets.model.MovieScore;
import com.snut.selltickets.model.Result;
import com.snut.selltickets.service.RankService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;import java.util.Set;RestController
RequestMapping(/userApi/RankCtl)
public class RankCtl {AutowiredRankService rankService;// 添加电影评分接口PostMapping(/add)public ResponseEntityString addMovieScore(RequestBody MovieScore movieScore) {rankService.addMovieScore(movieScore.getMovieId(),movieScore.getRating());return ResponseEntity.ok(电影评分成功);}// 获取排行榜前N名接口GetMapping(/topN)public ResponseEntitySetMovieScore getTopNRankings(RequestParam(n) int n) {SetMovieScore topNRankings rankService.getTopNRankings(n);return ResponseEntity.ok(topNRankings);}// 获取电影排名接口GetMapping(/movieRank)public ResponseEntityLong getMovieRank(RequestParam(movieId) String movieId) {Long userRank rankService.getMovieRank(movieId);return ResponseEntity.ok(userRank);}// 获取电影积分接口GetMapping(/movieRating)public ResponseEntityDouble getMovieScore(RequestParam(movieId) String movieId) {Double userScore rankService.getMovieScore(movieId);return ResponseEntity.ok(userScore);}}
3.6 测试
我这里是在前端简单模拟了一个测试器
3.6.1 测试 addMovieScore 接口 3.6.2 测试 getTopNRankings 接口 这里返回排行榜前topN(3)的电影信息
3.6.3 测试 getMovieRank接口 3.6.4 测试 getMovieScore接口 前端测试代码
templatediv idappdiv styleheight: 120px;/divmovieIdinput typetext v-modelform.movieId/ratinginput typetext v-modelform.rating/topNinput typetext v-modeln/div stylemargin-bottom: 30px;/divbutton stylewidth: 150px; height: 100px; clickadd()add/buttonbutton stylewidth: 150px; height: 100px; clicktopN()topN/buttonbutton stylewidth: 150px; height: 100px; clickgetMovieRank()getMovieRank/buttonbutton stylewidth: 150px; height: 100px; clickgetMovieScore()getMovieScore/button/div
/templatescriptexport default {data() {return {form:{movieId:,rating:},n:}},methods: {add() {this.$http.post(userApi/RankCtl/add,this.form).then((resp) {this.$message({message: resp.data,type: success});this.$router.go(0); //更新当前的路由 组件});},topN() {this.$http.get(userApi/RankCtl/topN?nthis.n).then((resp) {this.$message({message: resp.data,type: success});console.log(resp.data);});},getMovieRank() {this.$http.get(userApi/RankCtl/movieRank?movieIdthis.form.movieId).then((resp) {this.$message({message: resp.data,type: success});console.log(resp.data);});},getMovieScore() {this.$http.get(userApi/RankCtl/movieRating?movieIdthis.form.movieId).then((resp) {this.$message({message: resp.data,type: success});console.log(resp.data);});}},mounted() {}}
/scriptstyle scoped#app{width: 150px;margin: 0 auto;}
/style 完结撒花 博主WXg2279605572 欢迎大家与我交流