基于Redis的实时排行榜
发布日期:2021-11-15 14:57:37 浏览次数:28 分类:技术文章

本文共 5672 字,大约阅读时间需要 18 分钟。

此文档主要演示了如何使用 Spring Boot 集成Redis的实时排行榜

根据用户点赞数量,获取热点文章

在这里插入图片描述

文章实时排序接口类

/** * 文章实时排序接口类 * * @author xiehengxing * @date 2020/8/12 15:17 */public interface ArticleService {
/** * 文章详情key */ String ARTICLE_DETAIL_KEY = "article:detail:key:"; /** * 文章分值key */ String ARTICLE_SCORE_KEY = "article:score:key"; /** * 文章点赞用户key */ String ARTICLE_LIKE_USER_KEY = "article:like:user:key:"; /** * 创建文章 * * @param articleId * @param articleContent */ boolean createArticle(Long articleId, String articleContent); /** * 分页查询最受欢迎文章 * @param page * @param pageSize * @return */ List
getArticleSort(int page, int pageSize); /** * 用户点赞文章 * * @param userId * @param articleId */ boolean userLikeArticle(Long userId, Long articleId); /** * 清除文章点赞记录 * * @param articleId */ boolean clearLikeInfo(Long articleId);}
@Slf4j@Servicepublic class ArticleServiceImpl implements ArticleService {
@Resource private RedisTemplate redisTemplate; @Override public boolean clearLikeInfo(Long articleId) {
// 清除历史点赞用户 redisTemplate.delete(ARTICLE_LIKE_USER_KEY+ articleId); // 重置文章排序 redisTemplate.opsForZSet().add(ARTICLE_SCORE_KEY, articleId, 0); return true; } /** * 创建文章 * * @param articleId * @param articleContent */ public boolean createArticle(Long articleId, String articleContent) {
// 获取历史点赞用户 Long size = redisTemplate.opsForSet().size(ARTICLE_LIKE_USER_KEY+ articleId); // 添加文章到缓存排序列表 redisTemplate.opsForZSet().add(ARTICLE_SCORE_KEY, articleId, size); // 添加文章内容到缓存中 redisTemplate.opsForValue().set(ARTICLE_DETAIL_KEY+ articleId, articleContent, 1, TimeUnit.HOURS); return true; } /** * 用户点赞文章 * * @param userId * @param articleId */ public boolean userLikeArticle(Long userId, Long articleId) {
// 检查文章是否存在 Long index = redisTemplate.opsForZSet().rank(ARTICLE_SCORE_KEY, articleId); if(null == index){
return false; } // 检查用户是否已点赞该文章 boolean isLike = redisTemplate.opsForSet().isMember(ARTICLE_LIKE_USER_KEY + articleId, userId); if(isLike){
log.debug("用户:[{}]已点赞文章:[{}]", userId, articleId); return false; } // 增加文章点赞数量 // 记录文章点赞用户 redisTemplate.opsForZSet().incrementScore(ARTICLE_SCORE_KEY, articleId, 1); redisTemplate.opsForSet().add(ARTICLE_LIKE_USER_KEY+ articleId, userId); return true; } /** * 分页查询最受欢迎文章 * @param page * @param pageSize * @return */ public List
getArticleSort(int page, int pageSize) {
int start = (page - 1) * pageSize; int end = start + pageSize - 1; // 根据点赞数倒叙分页查询文章 Set
> tuples = redisTemplate.opsForZSet().reverseRangeByScoreWithScores(ARTICLE_SCORE_KEY, start, end); if(CollectionUtils.isEmpty(tuples)){
return Collections.EMPTY_LIST; } // 查询文章内容及点赞用户 List
list = new ArrayList<>(); for (DefaultTypedTuple
tuple: tuples) {
ArticleVO vo = new ArticleVO(); Long articleId = tuple.getValue(); vo.setArticleId(tuple.getValue()); vo.setScore(tuple.getScore()); // 查询文章内容 String content = (String) redisTemplate.opsForValue().get(ARTICLE_DETAIL_KEY + articleId); vo.setArticleContent(content); // 查询点赞用户 Set
userIds = redisTemplate.opsForSet().members(ARTICLE_LIKE_USER_KEY+ articleId); vo.setLikeUserIds(userIds); list.add(vo); } return list; }}

控制层

/** * @author xiehengxing * @date 2020/8/12 17:27 */@Controller@Slf4jpublic class ArticleController {
@Resource private ArticleService articleService; @RequestMapping(value ="/getArticle") public String getArticle(Model model) {
List
articleSort = articleService.getArticleSort(1, 10); model.addAttribute("list", articleSort); return "page/index"; } @RequestMapping(value ="/add") public String index(Model model) {
for (long i = 0; i < 10; i++) {
articleService.createArticle(i, "我是ID:"+ i + "的文章内容~~~"); } List
articleSort = articleService.getArticleSort(1, 10); model.addAttribute("list", articleSort); return "redirect:getArticle"; } @RequestMapping(value ="/like") public String like(Long articleId, Model model) {
if (null == articleId) {
model.addAttribute("errorMassage", "文章ID为空"); return "page/error"; } // 模拟随机用户ID Long userId = System.currentTimeMillis(); boolean flag = articleService.userLikeArticle(userId, articleId); if(!flag){
return "page/error"; } return "redirect:getArticle"; } @RequestMapping(value ="/clearLike") public String clearLike(Long articleId, Model model) {
if (null == articleId) {
model.addAttribute("errorMassage", "文章ID为空"); return "page/error"; } boolean flag = articleService.clearLikeInfo(articleId); if(!flag){
return "page/error"; } return "redirect:getArticle"; }}

index.html

序号 文章id 文章内容 排序 点赞用户 操作
点赞 清空点赞

转载地址:https://blog.csdn.net/qq_39739458/article/details/107990151 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Redis常见问题穿透、击穿、雪崩处理方案
下一篇:基于Redis的分布式共享锁

发表评论

最新留言

能坚持,总会有不一样的收获!
[***.219.124.196]2024年03月31日 22时52分06秒