SpringBoot整合Redis——实现点赞功能

目录

点赞功能

设计思路 

 实现

正在思考和学习的问题

回顾redis中的set 

使用方法

使用场景

回顾springboot整合redis

1.引入必要的依赖。

2.在配置文件application.properties/yml中 配置redis的连接信息

3. 测试


点赞功能

设计思路 

点赞功能的两个接口:

1.点赞,取消点赞;

2.通过用户id可以看到用户是否点赞;根据上传视频/动态查看总点赞数;

 实现

点赞的关键就是看用户是否点赞,已经重复的点赞不允许再点赞,即过滤重复,但是对于点赞这些高并发的场景,同一时间会有很多用户进行点赞, 一般使用缓存来处理,而不是直接查mysql。复习一下redis中的set。sadd进行点赞,screm取消点赞,scard点赞总数,sismember看用户是否点赞,smember看总共有哪些用户点赞

 @Resource
    RedisTemplate redisTemplate;
    @GetMapping(value = "/dolike")
    public String doLike(int postid,int userid) {
        String result = "";
        try {
            String key = "LIKE_KEY:" + postid;
            Long object = this.redisTemplate.opsForSet().add(key, userid);
            if (object == 1) {
                result = "点赞成功";
            } else {
                result = "你已重复点赞";
            }
            //   Log.info("查询结果: {}", object);
        } catch (Exception ex) {
            log.error("exception:", ex);
        }
        return result;
    }
      @GetMapping("/undolike")
    public String undolike(int postid,int userid){
        String result="";
        String key=Constants.LIKE_KEY+postid;
        long object=this.redisTemplate.opsForSet().remove(key,userid);
        if(object==1){
            result="取消成功";
            
        }else{
            result="你已重复取消点赞";
        }
        return result;
    }
    
     @GetMapping(value = "/getpost")
        public Map<String, Object> getpost(int postid, int userid) {
            Map<String, Object> map = new HashMap<>();
            try {
                String key = Constants.LIKE_KEY + postid;
                long size = this.redisTemplate.opsForSet().size(key);
                boolean isLike = this.redisTemplate.opsForSet().isMember(key, userid);
                map.put("size", size);
                map.put("isLike", isLike);
             //   Log.info("查询结果:" + map);
            } catch (Exception ex) {
                log.error("异常:" + ex);
            }
            return map;
        }
       
@GetMapping(value = "/likedetail")
        public Set<String> likedetail(int postid) {
            Set<String> set = null;
            try {
                String key = Constants.LIKE_KEY + postid;  // 拼接 Redis 键名
                set = this.redisTemplate.opsForSet().members(key);  // 获取集合元素
                log.info("查询结果:{}", set);
            } catch (Exception ex) {
                log.error("查询点赞详情异常:", ex);
            }
            return set;
        }

正在思考和学习的问题

点赞之类的高并发事件放在缓存里,那如何保证它的持久化?如何持久化到mysql或者磁盘?又该定时持久化还是🤔是否还会有线程安全问题? ......而且这些只是动态/帖子/视频id,用户id,并没有其点赞时间之类,后续完善。

12月14下午,从学长思路中学到了在redis中查询热点数据,其余数据的查询就在mysql中,热点,那就可以。跳表

回顾redis中的set 

使用方法

当你使用 Redis 中的 Set 数据结构时,可以按照以下步骤进行具体操作:

1. 添加成员到集合中:
   使用 SADD 命令将一个或多个成员添加到集合中。
 


   SADD key member1 member2 member3

2. 获取集合中的所有成员:
   使用 SMEMBERS 命令获取集合中的所有成员。
 


   SMEMBERS key
 

3. 检查成员是否存在于集合中:
   使用 SISMEMBER 命令检查指定成员是否存在于集合中,返回值为 1 表示存在,0 表示不存在。
 


   SISMEMBER key member

4. 获取集合中成员的数量
   使用 SCARD 命令获取集合中成员的数量。
 


   SISMEMBER key member
  

5. 从集合中移除成员:
   使用 SREM 命令从集合中移除一个或多个成员。
 


   SREM key member1 member2 member3

6. 计算集合的交集
   使用 SINTER 命令计算给定多个集合的交集,并返回结果。
 


   SINTER key1 key2 ... keyN
  

7. 计算集合的并集
   使用 SUNION 命令计算给定多个集合的并集,并返回结果。
   

  SUNION key1 key2 ... keyN



 8. 计算集合的差集
   使用 SDIFF 命令计算给定多个集合的差集,并返回结果。
 

 
   SDIFF key1 key2 ... keyN
  

使用场景

  1. 去重:Set中的元素不能重复,因此可以用来存储去重后的数据。

  2. 标签系统:可以将每个标签作为Set的一个元素,然后用Set进行标签的各种操作,比如求交集、并集、差集等,以便于实现文章、商品等的分类和搜索。

  3. 计数器:可以用Set来实现计数器,例如记录网站访问量、文章阅读数等,每次访问或阅读时,将对应的计数器加1即可。

  4. 共同好友:可以用Set来存储两个用户的好友列表,然后用Set进行好友的各种操作,比如求交集、并集等,以便于实现共同好友的功能。

  5. 排行榜:可以用Set来实现排行榜功能,例如记录网站访问量、文章阅读数等,每次访问或阅读时,将对应的元素加入Set,并按照相应的规则进行排名

回顾springboot整合redis

1.引入必要的依赖。

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId> 
        </dependency>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>like</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>like</name>
    <description>like</description>
    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.7.6</spring-boot.version>
    </properties>
    <dependencies>
        <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>
        <!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>4.4.2</version>
        </dependency>
 
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
         
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-redis</artifactId>
            <version>2.7.17</version>
        </dependency>

    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <configuration>
                    <mainClass>com.example.demo.LikeApplication</mainClass>
                    <skip>true</skip>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

2.在配置文件application.properties/yml中 配置redis的连接信息

spring:
  redis:
    # Redis服务器地址
    host: 
    # Redis服务器端口号
    port: 6379
    # 使用的数据库索引,默认是0
    database: 0
    # 连接超时时间
    timeout: 1800000
     # 设置密码
    password: 
    lettuce:
      pool:
        # 最大阻塞等待时间,负数表示没有限制
        max-wait: -1
        # 连接池中的最大空闲连接
        max-idle: 5
        # 连接池中的最小空闲连接
        min-idle: 0
        # 连接池中最大连接数,负数表示没有限制
        max-active: 20

  Redis 配置类 RedisConfig

package com.example.demo.config;

import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.net.UnknownHostException;

@EnableCaching
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory("localhost", 6379);
    }
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(factory);

        // 设置key的序列化器
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());

        // 设置value的序列化器
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());

        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
    @Bean
    @ConditionalOnMissingBean(StringRedisTemplate.class)
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory)
            throws UnknownHostException {
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);

        // 设置key的序列化器
        template.setKeySerializer(new StringRedisSerializer());

        // 设置value的序列化器
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());

        return template;
    }


}

3. 测试

package com.example.demo.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
@RequestMapping("/redisTest")
public class RedisConnectTest {
    @Resource
    private RedisTemplate redisTemplate;
    @GetMapping("/test")
    public String testRedis(){
        redisTemplate.opsForValue().set("name","lucy");
        Object name = redisTemplate.opsForValue().get("name");
        return (String)name;
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Spring之容器:IOC(1)

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…

自动封箱打包码垛缠绕流水线案例

广西交投在某地新建工厂后&#xff0c;需要建设一条生产隧道灯&#xff0c;后段自动封箱打包码垛缠绕包装线。 凯隆包装在深入了解客户需求后&#xff0c;结合客户实际生产情况&#xff0c;为客户量身定制了集智能感应系统、产品自动折盖上下封箱、捆扎两道打包带、码垛机械臂自…

Linux平台下HTTP协议使用指南与代码展示

在Linux平台下&#xff0c;HTTP协议的应用非常广泛&#xff0c;它被用于Web开发、网络爬虫、API调用等场景。了解并掌握HTTP协议&#xff0c;对于Linux系统的开发和使用都非常重要。下面&#xff0c;我们将为您介绍Linux平台下HTTP协议的使用指南&#xff0c;并通过代码展示来帮…

设计模式(3)--对象结构(4)--装饰

1. 意图 动态地给一个对象添加一些额外的功能。 2. 四种角色 抽象组件(Component)、具体组件(Concrete Component)、抽象装饰(Decorator)、具体装饰(Concrete Decorator) 3. 优点 3.1 比静态继承更灵活。 3.2 避免在层次结构高层的类有太多的特征。"即用即付"&…

【洛谷算法题】P1424-小鱼的航程(改进版)【入门2分支结构】Java题解

&#x1f468;‍&#x1f4bb;博客主页&#xff1a;花无缺 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 花无缺 原创 收录于专栏 【洛谷算法题】 文章目录 【洛谷算法题】P1424-小鱼的航程&#xff08;改进版&#xff09;【入门2分支结构】&#x1f30f…

程序员必备算法

欢迎关注博主 Mindtechnist 或加入【智能科技社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和技术。关…

60.Sentinel源码分析

Sentinel源码分析 1.Sentinel的基本概念 Sentinel实现限流、隔离、降级、熔断等功能&#xff0c;本质要做的就是两件事情&#xff1a; 统计数据&#xff1a;统计某个资源的访问数据&#xff08;QPS、RT等信息&#xff09; 规则判断&#xff1a;判断限流规则、隔离规则、降级规…

Linux下I2C调试工具--for--Zynq MPSOC/Jetson Xavier

Linux下I2C调试工具 1、简介 i2c-tools是一个专门调试i2c的工具&#xff0c;无需编写任何代码即可轻松调试IC设备&#xff0c;可获取挂载的设备及设备地址&#xff0c;还可以在对应的设备指定寄存器设置值或者获取值等功能。i2c-tools有如下几个常用测试命令i2cdetect, i2cdu…

【Go】基于GoFiber从零开始搭建一个GoWeb后台管理系统(四)用户管理、部门管理模块

第一篇&#xff1a;【Go】基于GoFiber从零开始搭建一个GoWeb后台管理系统&#xff08;一&#xff09;搭建项目 第二篇&#xff1a;【Go】基于GoFiber从零开始搭建一个GoWeb后台管理系统&#xff08;二&#xff09;日志输出中间件、校验token中间件、配置路由、基础工具函数。 …

新手运行若依项目|若依项目各部分介绍|并修改自己需要的页面

新手运行若依项目|若依项目各部分介绍|并修改自己需要的页面 文章目录 新手运行若依项目|若依项目各部分介绍|并修改自己需要的页面前言IEDA如何运行若依项目若依项目目录简介ruo-yi common工具类ruoyi-framework 框架核心其他部分ruo一admin后台服务通用配置 application.yml数…

STM32 TIM定时中断设计

单片机学习 目录 文章目录 一、定时器定时中断设计步骤 二、定时器配置 1.RCC开启时钟 2.选择时钟源 3.配置时基单元 4.配置输出中断控制 5.配置NVIC 6.运行控制 三、设计中断函数 总结 一、定时器定时中断设计步骤 定时中断基本框架结构图&#xff1a; 根据结构图可按步骤配置…

AWS RDS慢日志文件另存到ES并且每天发送邮件统计慢日志

1.背景&#xff1a;需要对aws rds慢日志文件归档到es&#xff0c;让开发能够随时查看。 2.需求&#xff1a;并且每天把最新的慢日志&#xff0c;过滤最慢的5条sql 发送给各个产品线的开发负责人。 3.准备&#xff1a; aws ak/sk &#xff0c;如果rds 在不同区域需要认证不同的…

【Linux】进程周边005之环境变量

&#x1f440;樊梓慕&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》《Linux》 &#x1f31d;每一个不曾起舞的日子&#xff0c;都是对生命的辜负 目录 前言 1.环境变量是什么&#xff1…

工具化法则

《卓越成效的程序员》是若干程序员系列书籍我比较喜欢的一本&#xff0c;类似的还有《卓越程序员密码》等。《卓越成效的程序员》高明之处是不仅仅给出原则&#xff0c;还大谈工具和代码&#xff0c;这如同诸多鸡汤文在”布道”的层面之下实战干货&#xff0c;深得广大从业人员…

使用openMVS库,在VS2022中启用c++17标准编译仍然报错

使用openMVS库&#xff0c;在VS2022中启用c17标准编译仍然报错 现象 项目中引用了某些开源库&#xff08;例如openmvs2.1.0&#xff09;&#xff0c;编译时要求启用编译器对c17的支持。 没问题&#xff01;大家都知道在下图所示的位置调整C语言标准&#xff1a; 但是&#…

【Transformer】Transformer and BERT(1)

文章目录 TransformerBERT 太…完整了&#xff01;同济大佬唐宇迪博士终于把【Transformer】入门到精通全套课程分享出来了&#xff0c;最新前沿方向 学习笔记 Transformer 无法并行&#xff0c;层数比较少 词向量生成之后&#xff0c;不会变&#xff0c;没有结合语境信息的情…

动态加载库

no_mangle 不要改标识符 首先是认识这个标注&#xff1a;mangle&#xff0c;英文的含义“撕裂、碾压”。我第一次把这个单次误以为是manage&#xff0c;说实话两个单词还挺像的。 RUS中函数或静态变量使用#[no_mangle]这个标注属性后&#xff0c;编译器就不会修改它们的名字了…

机器学习 | KNN算法

一、KNN算法核心思想和原理 1.1、怎么想出来的&#xff1f; 近朱者赤&#xff0c;近墨者黑&#xff01; 距离决定一切、民主集中制 1.2、基本原理 —— 分类 k个最近的邻居 民主集中制投票分类表决与加权分类表决 1.3、基本原理 —— 回归 计算未知点的值决策规则不同均值法与…

windows10-EMQX与MQTTX的安装及配置使用教程

windows10-EMQX安装及配置使用教程 一、下载安装1.1 下载1.2 安装1.3 设置开机自启动 二、连接MQTT2.1 MQTT下载安装2.1.1 下载2.1.2 安装及配置 三、EMQX常用命令 本文介绍的是在windows10系统下的emqx的安装、配置及使用教程。 一、下载安装 1.1 下载 下载链接&#xff1a…

设计模式之创建型设计模式(一):单例模式 原型模式

单例模式 Singleton 1、什么是单例模式 在软件设计中&#xff0c;单例模式是一种创建型设计模式&#xff0c;其主要目的是确保一个类只有一个实例&#xff0c;并提供一个全局访问点。 这意味着无论何时需要该类的实例&#xff0c;都可以获得相同的实例&#xff0c;而不会创建…