《分布式中间件技术实战:Java版》学习笔记(三):Redis实现点赞、取消赞功能

用户在发布内容(包括博客、想法、日记等等)时,后台数据入库后,要往Redis的有序集合添加一条分数为0的记录。这个有序集合是用来对内容点赞量做排序的。同时,可以记录用户操作日志。

@Override
public String insertArticle(ArticleParams articleParams) {String uuid = UUID.randomUUID().toString();Article article = new Article();article.setAuthor(articleParams.getAuthor());article.setContent(articleParams.getContent());article.setTitle(articleParams.getTitle());article.setArticleUuid(uuid);save(article);//写redisredisTemplate.opsForZSet().add(ARTICLE_LIKE_COUNT, uuid, 0);UserLog userLog = new UserLog();userLog.setUserType("publish");userLog.setArticleUuid(uuid);userLog.setUserId(articleParams.getAuthor());userLogMapper.insert(userLog);return uuid;
}

一般地,用户点击点赞图标,如果之前点赞过,就是取消点赞;如果之前没有点赞过,就是点赞。后台怎么判断是否点赞过呢?

点赞时,后台会把用户ID加入到该篇内容的点赞用户集合中,然后内容点击量加一。取消点赞时,后台将用户ID从集合中移除,内容点击量减一。

用户刷新到这篇内容时,可以调用后台接口,根据用户ID是否在该篇内容的点赞用户集合中,判断是否点赞过。

我这里把判断用户ID是否在集合中、添加/移除用户ID、点击量加/减一这三个操作放在一个lua脚本中,作为一个原子性操作。

Redis点赞、取消赞

@Override
public String likeArticle(LikeArticleParams likeArticleParams) {String articleUuid = likeArticleParams.getArticleUuid();int userId = new Random().nextInt(100000);//异步发送到消息队列,限流 保证原子性boolean result = likeArticle(articleUuid, userId);//数据库写操作记录UserLog userLog = new UserLog();userLog.setUserType("like");userLog.setArticleUuid(articleUuid);userLog.setUserId(userId);if(result) {//点赞需要推送消息给文章作者} else {userLog.setUserType("unlike");}userLogMapper.insert(userLog);return "success";
}public boolean likeArticle(String articleUuid, int userId) {String likeArticleByUuidSet = "article:like:set:" + articleUuid;String redisScript = "if redis.call('exists', KEYS[1]) == 1 and redis.call('sismember', KEYS[1], ARGV[2]) == 1" +" then " +"   redis.call('zincrby', KEYS[2], -1, ARGV[1])" +"   redis.call('srem', KEYS[1], ARGV[2])" +"   return 0 " +" else " +"   redis.call('zincrby', KEYS[2], 1, ARGV[1])" +"   redis.call('sadd', KEYS[1], ARGV[2])" +"   return 1 " +" end ";DefaultRedisScript defaultRedisScript = new DefaultRedisScript(redisScript, Boolean.class);List<String> keys = new ArrayList();keys.add(likeArticleByUuidSet);keys.add(ARTICLE_LIKE_COUNT);boolean result = (boolean) redisTemplate.execute(defaultRedisScript, keys, articleUuid, userId);return result;
}

article:like:set是Redis的set集合,scard查询多少用户点赞了该内容,srandmember随机返回一个点赞用户。
article:like:count是Redis的sorted set集合,srange返回指定排序位的成员,zscore返回成员的点赞量。
在这里插入图片描述
附上我用的数据库表

CREATE TABLE `article`  (`id` int(0) NOT NULL AUTO_INCREMENT,`article_uuid` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '文章唯一标识',`title` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '标题',`content` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '内容',`author` int(0) NULL DEFAULT NULL COMMENT '用户主键',`create_time` timestamp(0) NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`enable_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '1' COMMENT '有效标识 1有效 0无效',`like_count` int(0) NULL DEFAULT NULL COMMENT '点赞数',`comment_count` int(0) NULL DEFAULT NULL COMMENT '评论数',`update_time` timestamp(0) NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间',PRIMARY KEY (`id`) USING BTREE
) 
CREATE TABLE `user_log`  (`id` int(0) NOT NULL AUTO_INCREMENT,`user_id` int(0) NULL DEFAULT NULL,`article_uuid` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,`user_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户类型like 点赞 unlike取消点赞 pulish发布文章',`comment` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '评论内容',`create_time` timestamp(0) NULL DEFAULT CURRENT_TIMESTAMP,`enable_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '1' COMMENT '有效1 无效0',PRIMARY KEY (`id`) USING BTREE
)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/20824.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

react使用SVGA特效 常用api

下载插件 npm install svgaplayerweb --save react中代码 import React, { useEffect } from react; import SVGA from svgaplayerweb const Svga () > {const bofang () > {var player new SVGA.Player(#demoCanvas);//创建实例var parser new SVGA.Parser(#demo…

AR增强现实技术解决企业远程协作需求

随着科技的不断发展&#xff0c;AR(增强现实)远程协同系统已经成为了一种新型的工作方式。这种系统利用AR技术将虚拟信息叠加到现实世界中&#xff0c;从而实现异地高效协作。 由广州华锐互动开发的AR远程协同系统&#xff0c;广泛应用于各个行业的远程协作场景中&#xff0c;…

Pycharm专业版连接远程GPU服务器+xshell7和xrtp7下载

这篇博客就带大家手把手用pycharm连接远端服务器&#xff0c;用服务器上的GPU跑代码。其中有很多雷点&#xff0c;都一一帮大家踩了&#xff0c;所以这也是一篇避雷篇。文章附pycharm专业版下载链接&#xff0c;xshell7和xrtp7的下载和使用说明&#xff0c;希望可以给大家带来帮…

js手动画平滑曲线,贝塞尔曲线拟合

效果图&#xff1a; 代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><meta http-equiv"…

postgresql 数据库 重建索引 所需时间测试

postgresql 数据库 重建索引 所需时间测试 文章目录 postgresql 数据库 重建索引 所需时间测试前言测试前准备重建索引前数据库状态测试计划重建索引命令测试开始1.先对表2进行测试2. 表3测试3. 表1测试 &#x1f308;后记 前言 众所周知&#xff0c;postgresql数据库使用久了…

layui入门

layui入门 一.ayui简介1.简单易用2.组件丰富3.高度定制化4.响应式布局5.轻量灵活 2.layui的入门基础操作3.登录实例4.注册实例 一.ayui简介 Layui&#xff08;流行音 “layui”&#xff0c;来自“领域的模块化”&#xff09;是一款前端UI框架&#xff0c;专注于提升 Web 开发效…

解决microsoft windows 恶意软件删除工具 占用内存高

1、winR快捷键&#xff0c;输入regedit&#xff0c;按回车键进入注册表编辑器 2、定位到 \HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\ 并创建新项MRT 3、 新建DWORD(32)值&#xff0c;命名为DontOffer ThroughWUAU,数值数据为1; 4、以管理员身份运行命令提示符&#x…

论文(1)——大家说SCI的一区二区和CCF中A类B类是什么意思?

文章目录 引言问题描述问题解决CCF 和A、B、C类CCF注意事项 SCI和一区、二区如何判定你找的论文所属的会议或期刊是几区或者几类&#xff1f;使用特定的网站查询使用浏览器插件 一年之内的应该投什么刊物&#xff1f; 总结参考 引言 已经研一暑假了&#xff0c;周围很多人已经…

【测试开发】Junit 框架

目录 一. 认识 Junit 二. Junit 的常用注解 1. Test 2. Disabled 3. BeforeAll 4. AfterAll 5. BeforeEach 6. AfterEach 7. 执行测试 三. 参数化 1. 引入依赖 2. 单参数 3. 多参数 3.1 通过CSV实现 3.2 通过方法实现 4. 测试用例的执行顺序 四. 断言 五…

系统架构设计师-项目管理

目录 一、盈亏平衡分析 二、进度管理 1、WBS工作分解结构 2、进度管理流程 &#xff08;1&#xff09;活动定义 &#xff08;2&#xff09;活动排序 &#xff08;3&#xff09;活动资源估算&#xff1a; &#xff08;4&#xff09;活动历时估算&#xff1a; &#xff08;5&…

ASP.NET版本泄露【原理扫描】

如果想屏蔽 Server&#xff0c;X-AspNet-Version&#xff0c;X-AspNetMvc-Version 和 X-Powered-By&#xff0c;需要增加&#xff1a; <httpProtocol><customerHeaders><remove name"Server" /><remove name"X-AspNet-Version" />…

volatile原理剖析和实例讲解

一、是什么 volatile是Java的一个关键字&#xff0c;是Java提供的一种轻量级的同步机制&#xff0c; 二、能做什么 保证了不同线程对这个变量进行操作时的可见性&#xff0c;有序性。 三、可见性 可见性主要是指一个线程修改了共享变量的值&#xff0c;另一个线程可以看见…