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

news2024/9/22 4:04:09

用户在发布内容(包括博客、想法、日记等等)时,后台数据入库后,要往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);

    //写redis
    redisTemplate.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.coloradmin.cn/o/733083.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++常用库函数 4.数学函数

函数名&#xff1a;abs 函数原型&#xff1a;int abs(int n) ; 参数 in 需要求绝对值的整数。 所需头文件&#xff1a;<cstdlib>或<cmath> 功能和返回值&#xff1a;返回 n 的绝对值&#xff1b;没有错误返回函数名&#xff1a;acos 函数原型&#xff1a;doubl…

Cocos Creator 打包 Android 原生,如何配置构建环境?关键就一点

前段时间&#xff0c;有好几位老铁留言 Cocos Creator 打包 Android 原生出现问题&#xff1a;一种是构建失败&#xff0c;一种是运行起来报错&#xff01; 其实&#xff0c;我也是有好长一段时间没有碰过 Android 原生了&#xff0c;而且我这台电脑&#xff0c;环境都没有配置…

idea创建web项目没有jsp选项,不识别jsp,没有tomcat选项

如果你的idea的web项目中没有jsp选项 同时也不识别jsp 那么建议你检查一下你的idea是否为社区版 如果是社区版那么没有jsp的问题无法解决&#xff0c;这只是无法识别&#xff0c;但是语句对的可以正常运行 解决这个问题建议换个idea 至于tomcat&#xff0c; 在plugins中搜s…

axios的学习

axios是基于promise对ajax的一种封装 //将省份信息打印到网页上 <p class"my-p"></p> <script src"https://unpkg.com/axios/dist/axios.min.js"></script> <script>axios({url:http://hmajax.itheima.net/api/province}).…

【PCIE】hot-reset和link disable

Hot reset 规则 如果上游伪端口&#xff08;Pseudo Port&#xff09;的任何一个通道连续接收到两个带有热复位位设置为1b、禁用链路位和回环位设置为0b的TS1有序集合&#xff0c;并且两个伪端口上的任何一个通道&#xff08;接收到TS1有序集合&#xff09;要么收到EIOS&#xf…

java方法的覆盖(Overriding )和隐藏(Hiding)

Java方法的覆盖&#xff08;Overriding &#xff09;针对的是实例方法&#xff08;即非静态方法&#xff09;&#xff0c;而方法的隐藏&#xff08;Hiding&#xff09;针对的是类方法&#xff08;即静态方法&#xff09;。 方法的覆盖和隐藏指的是子类对从父类继承的方法进行重…

基于simulink基于颜色分割方法跟踪人员的面部和手部(附源码)

一、前言 此示例演示如何使用基于颜色的分割方法跟踪人员的面部和手部。 二、模型 下图显示了颜色分割示例模型&#xff1a; 三、颜色分割结果 为了为示例创建准确的颜色模型&#xff0c;处理了许多包含肤色样本的图像&#xff0c;以计算 Cb 和 Cr 颜色通道的均值 &#xf…

基于Unity2017版本的2D3D Infinite Runner Engine 1.5.1二维三维跑酷游戏模板

基于Unity2017版本的2D3D Infinite Runner Engine 1.5.1二维三维跑酷游戏模板 有多种游戏模式 还有个竖屏的玩法 工程地址&#xff1a;https://download.csdn.net/download/Highning0007/88020755

MFC学习日记(一)——创建新项目

此系列所有文章参考链接&#xff1a;http://www.jizhuomi.com/software/141.html 点击file新建项目创建一个MFC新项目 点击确定 点击下一步 选择应用程序类型 我们看到有四种类型&#xff1a;Single document&#xff08;单文档&#xff09;、Multiple documents&#xff…

传统图像处理之目标检测——人脸识别

代码实战&#xff1a;人脸识别 import numpy as np import cv2 img cv2.imread("3.webp")face_cascade cv2.CascadeClassifier(r./haarcascade_frontalface_default.xml)gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)#探测图片中的人脸 faces face_cascade.detec…

Android kotlin 实现把多个控件整体上下拉回弹功能(添加是否禁用顶部和底部回弹的参数设置,以及回弹效果结束监听)

目录 一、实现效果二、源码1、上下拉回弹,自定义ScrollView2、主activity一、实现效果 二、源码 1、上下拉回弹,自定义ScrollView 上下拉回弹,自定义ScrollView,ReboundScrollView.kt package com.example.myapplication3.myviewimport android.content.Context import

Netty核心技术九--TCP 粘包和拆包及解决方案

1. TCP 粘包和拆包基本介绍 **TCP是面向连接的&#xff0c;面向流的&#xff0c;提供高可靠性服务。收发两端&#xff08;客户端和服务器端&#xff09;都要有一一成对的socket&#xff0c;因此&#xff0c;发送端为了将多个发给接收端的包&#xff0c;更有效的发给对方&#x…

OpenCV 入门教程:图像的基本操作和处理

OpenCV 入门教程&#xff1a;图像的基本操作和处理 导语一、图像的基本操作1.1 获取图像的大小1.2 访问图像的像素1.3 修改图像的像素值 二、图像的基本处理2.1 图像的灰度化2.2 图像的平滑处理2.3 图像的边缘检测 总结 导语 在计算机视觉和图像处理领域&#xff0c;对图像进行…

Spring Boot 中的 CompletableFuture 类是什么,如何使用?

Spring Boot 中的 CompletableFuture 类是什么&#xff0c;如何使用&#xff1f; 介绍 在开发企业级应用程序时&#xff0c;我们经常需要异步执行任务。异步执行任务可以提高应用程序的性能和响应能力。在 Java 8 中&#xff0c;引入了 CompletableFuture 类&#xff0c;它提…

zabbix 监控 windows 系统、java应用、SNMP

目录 一、部署 zabbix 监控 windows系统 1.下载 Windows 客户端 Zabbix agent 2 2.安装客户端&#xff0c;在监控的windows主机上配置 3.在服务端 Web 页面添加主机&#xff0c;关联模板 二、部署 zabbix 监控 Java应用 1.客户端开启 java jmxremote 远程监控功能 1.1配置…

finalshell上传文件到虚拟机一直失败

目录 1.首先看一下你的虚拟机的可用空间是否足够 2.查看是否是root用户 1.首先看一下你的虚拟机的可用空间是否足够 在finalshell查看即可 如果空间不够则将虚拟机关机 &#xff0c;右键虚拟机找到设置&#xff0c;找到硬盘 &#xff08;我这里演示的是VMwareFusion&#xff…

Linux--冯诺依曼体系结构

【Linux】冯诺依曼体系结构、操作系统及进程概念_linux io 冯诺依曼_平凡的人1的博客-CSDN博客 存储器指的是内存还是磁盘&#xff1f; 内存 输入设备&#xff1a;键盘、摄像头、话筒、磁盘、网卡... 输出设备&#xff1a;显示器、音响、磁盘、网卡... CPU: 运算器&#x…

Jetpack compose——深入了解Diffing

Diffing是什么 "Diffing" 是 Jetpack Compose 中用于优化性能的一种技术。它的工作原理是比较新旧 UI 树&#xff0c;并只更新实际发生变化的部分。这意味着即使你的应用有大量的 UI&#xff0c;Compose 也能保持高效的性能。 当 Composable 函数被重新调用&#x…

医学图像增强系统的设计_kaic

目录 1绪论 1.1课题背景 1.2医学图像增强以及相关理论的现状2 1.3本文内容安排 2图像增强技术 2.1空域增强方法 2.1.1空域点运算增强方法 2.1.2空域滤波增强方法 2.2频域增强算法 2.2.1低通滤波 2.2.2高通滤波 2.2.3同态滤波 2.3本章小结 3医学图像增强算法 3.1医学图像的特点 …

Unity跑酷小游戏-警察捉小偷

Unity跑酷小游戏-警察捉小偷 WRPUltimate3DEndlessRunnerKit2017 采用Unity2017版本运行 NGUI版本较旧&#xff0c;需要更新NGUI的版本或者换成UGUI Assets/NGUI/Scripts/UI/UIAnchor.cs(73,53): error CS0619: UnityEngine.RuntimePlatform.WindowsWebPlayer is obsolete:…