目录
2.在配置文件application.properties/yml中 配置redis的连接信息
点赞功能的两个接口:
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 数据结构时,可以按照以下步骤进行具体操作:
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 ?
使用场景
去重:Set中的元素不能重复,因此可以用来存储去重后的数据。
标签系统:可以将每个标签作为Set的一个元素,然后用Set进行标签的各种操作,比如求交集、并集、差集等,以便于实现文章、商品等的分类和搜索。
计数器:可以用Set来实现计数器,例如记录网站访问量、文章阅读数等,每次访问或阅读时,将对应的计数器加1即可。
共同好友:可以用Set来存储两个用户的好友列表,然后用Set进行好友的各种操作,比如求交集、并集等,以便于实现共同好友的功能。
排行榜:可以用Set来实现排行榜功能,例如记录网站访问量、文章阅读数等,每次访问或阅读时,将对应的元素加入Set,并按照相应的规则进行排名。
<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>
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;
}
}
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;
}
}