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

发布时间:2023年12月17日

目录

点赞功能

设计思路?

?实现

正在思考和学习的问题

回顾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;
    }
}

文章来源:https://blog.csdn.net/m0_74106420/article/details/134968107
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。