为什么要使用Redis实现点赞?Mysql不行吗?:
- 如果用户频繁点赞、取消点赞那么会给数据库带来很大的压力,而缓存可以有效减少数据库的压力。
- 因为Redis是基于内存的,所以效率很快,而Mysql是基于硬盘的,读写效果没有Redis快的。
一、设计思路
使用Redis的Set,例如我点赞一个帖子;
帖子作为Key,点赞的用户id作为Value,最后计算Set集合长度就可以得出点赞数量。
二、代码实现
1. 拼接字符
/**
* ClassName: LikeUtils
*
* @author Jay01is
* @version 1.0
* @date 2023/3/3 20:25
*/
public class LikeUtils {
/**
* 点赞人
*/
public static String IS_LIKE = "like:%s";
/**
* 点赞帖子
*/
public static String LIKE_COUNT = "like:post:%s";
/**
* 拼接
* @param userId
* @return
*/
public static String like(Integer userId) {
return String.format(IS_LIKE, userId);
}
public static String likeCount(Integer postId) {
return String.format(LIKE_COUNT, postId);
}
}
2. 点赞实现
/**
* ClassName: LikeController
*
* @author Jay01is
* @version 1.0
* @date 2023/3/3 20:01
*/
@Slf4j
@RestController
@RequestMapping("/like")
public class LikeController {
/**
* 拟定用户id
*/
private Integer userId = 1;
@Autowired
private StringRedisTemplate stringRedisTemplate;
/**
* 点赞
* @param postId 帖子id
* @return
*/
@GetMapping("/giveLikes/{postId}")
public Boolean giveLikes(@PathVariable Integer postId){
// 判断用户是否给此点赞过.
if (stringRedisTemplate.opsForSet().isMember(LikeUtils.likeCount(postId),LikeUtils.like(userId))) {
return false;
}
// 点赞 帖子Id为Key 用户Id为Value 点赞数计算Set集合长度即可
stringRedisTemplate.opsForSet().add(LikeUtils.likeCount(postId),LikeUtils.like(userId));
return true;
}
}
3. 注意事项
- 放在缓存中的数据是不太安全的,需要持久化到数据库中,可以跑一个定时任务,定时持久化到数据库。
- 防止恶意请求,需要对接口做限制,比如一分钟之内只能点赞、取消4次。
- 用户的标识可以从前端传来的Jwt解码拿到。