Spring 整合 Redis
Redis 配置
// 进入 Redis 安装目录
cd /usr/local/redis
// 使用指定的配置文件 redis.conf 来配置 Redis 的运行参数设置启动后配置文件
./bin/redis-server ./redis.conf
// 启动 Redis 服务器
./bin/redis-cli
// 退出 Redis 客户端
quit
// 退出 Redis 服务器
./bin/redis-cli shutdown
pom.xml
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.8.0</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.5.0.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.8.0</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.5.0.RELEASE</version>
</dependency>
application.xml
<!-- 给 redis 包开启扫描 -->
<context:component-scan base-package="com.free.redis" />
<!-- 计时器扫描 -->
<task:annotation-driven />
<!-- Jedis -->
<bean id="connectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:host-name="192.168.203.128" p:port="6379" />
<bean class="org.springframework.data.redis.core.RedisTemplate" id="redisTemplate">
<property name="connectionFactory" ref="connectionFactory"/>
<property name="keySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="valueSerializer">
<bean class="org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer">
<constructor-arg name="type" value="java.lang.Object" />
</bean>
</property>
</bean>
数据结构
字符串 string
哈希 hash
字符串列表 list
字符串集合 set
有序字符串集合 sorted set
这里我们选用 set 类型来存储
@Autowired
private RedisTemplate redisTemplate;
@Test
public void testSets() {
String redisKey = "test";
redisTemplate.opsForSet().add(redisKey,"test1","test2","test3");
System.out.println(redisTemplate.opsForSet().size(redisKey));
System.out.println(redisTemplate.opsForSet().pop(redisKey));
System.out.println(redisTemplate.opsForSet().members(redisKey));
}
点赞
当涉及到频繁的点赞操作时,将点赞信息存储在 Redis 中可以减轻数据库负载,提高系统性能和响应速度,可以通过以下后端代码实现
Controller
@RequestMapping("like")
public ResultInfo like(@RequestParam String commentId, @RequestParam String userId) {
commentService.like(commentId, userId);
// 获取点赞数量和点赞状态
long likeCount = commentService.findLikeCount(commentId);
boolean likeStatus = commentService.findLikeStatus(userId, commentId);
// 构建并返回 JSON 格式的响应
ResultInfo resultInfo = new ResultInfo();
resultInfo.setData(likeCount);
resultInfo.setFlag(likeStatus);
return resultInfo;
}
@RequestMapping("likeCounts")
public ResultInfo likeCounts(@RequestParam String commentId, @RequestParam String userId) {
// 获取点赞数量和点赞状态
long likeCount = commentService.findLikeCount(commentId);
boolean likeStatus = commentService.findLikeStatus(userId, commentId);
ResultInfo resultInfo = new ResultInfo();
resultInfo.setData(likeCount);
resultInfo.setFlag(likeStatus);
return resultInfo;
}
Service
@Override
public void like(String commentId, String userId) {
String key = "comment" + commentId;
// 判断用户点赞状态
boolean isMember = redisTemplate.opsForSet().isMember(key, userId);
if (isMember) {
redisTemplate.opsForSet().remove(key, userId);
} else {
redisTemplate.opsForSet().add(key, userId);
}
}
@Override
public long findLikeCount(String commentId) {
String key = "comment" + commentId;
return redisTemplate.opsForSet().size(key);
}
@Override
public boolean findLikeStatus(String userId, String commentId) {
String key = "comment" + commentId;
return redisTemplate.opsForSet().isMember(key, userId) ? true : false;
}
浏览量
当用户每次访问帖子时,通常会记录一次浏览量。但如果访问量过大,这可能会给服务器带来巨大的压力。为了缓解这种压力,可以将浏览量信息存储在 Redis 中,将 Redis 作为缓存,然后设置一个定时器,每隔一分钟将 Redis 中的浏览量数据存储到 MySQL 数据库中,确保数据的持久性,可以通过以下后端代码实现
Controller
@RequestMapping("view")
public ResultInfo view(@RequestParam String userId, @RequestParam String postId) {
postService.view(userId, postId);
ResultInfo resultInfo = new ResultInfo();
resultInfo.setFlag(true);
return resultInfo;
}
Service
@Override
public void view(String userId, String postId) {
String key = "post" + postId;
boolean isMember = redisTemplate.opsForSet().isMember(key, userId);
if (!isMember) {
// 如果用户未被记录在帖子的浏览量缓存中,添加用户并将帖子ID加入到缓存集合
redisTemplate.opsForSet().add(key, userId);
redisTemplate.opsForSet().add("postCache", postId);
}
}
RedisData
@Scheduled(cron = "0 */1 * * * *")
public void save2() {
Set<String> postCache = redisTemplate.opsForSet().members("postCache");
for (String postId : postCache) {
// 获取帖子浏览量的缓存集合大小
Long size = redisTemplate.opsForSet().size("post" + postId);
int newView = size.intValue();
int oldView = postMapper.getViews(postId);
// 计算新的浏览量总数,然后更新数据库中的浏览量
postMapper.updateView(newView + oldView, postId);
redisTemplate.opsForSet().remove("postCache", postId);
Set<String> postSet = redisTemplate.opsForSet().members("post" + postId);
// 遍历每个用户的浏览并从帖子的缓存集合中移除
for (String userId : postSet) {
redisTemplate.opsForSet().remove("post" + postId, userId);
}
}
}
Mapper
@Update("update post set view = #{count} where id = #{postId}")
void updateView(@Param("count") int count, @Param("postId") String postId);
@Select("select view from post where id = #{postId}")
int getView(String postId);