基于 SSM 论坛项目点赞、浏览量的 Redis 应用

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);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值