586
社区成员




这个作业属于哪个课程 | 软件工程-23年春季学期 |
---|---|
这个作业要求在哪里 | 软件工程实践总结&个人技术总结 |
这个作业的目标 | 个人技术总结 |
其他参考文献 | 《构建之法》 |
Redis实现点赞点踩功能,因为点赞功能经常会被使用,热门文章可能在同一时刻会出现大量点赞的情况,
如果由mysql数据库直接进行点赞记录的更新,数据库的压力会很大,所以采用Redis数据库进行优化,
Redis中的数据存储在内存中,内存的读写速度都很快,因此能够满足点赞模块的性能要求。学习该技术
的原因的团队项目需要用到。
下面基于我们团队项目的实现来讲解,我们的应用场景是对真题进行点赞点踩。
使用springboot框架来实现点赞,首先在pom.xml文件中导入redis的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
在application.properties文件中编写配置信息
//其实下面的配置可以不写,如果不写的话就用的是默认值
spring.redis.host=127.0.0.1 //redis数据库地址,默认值是127.0.0.1
spring.redis.port=6379 //redis端口,默认是6379
spring.redis.database=0 //选择要使用的是几号数据库,默认是0
spring.redis.password=123456 //如果没有密码,这行可以不写,默认是没有
编写控制层代码(controller)
点赞控制类
@RestController
@CrossOrigin
@RequestMapping("like")
public class LikeController {
@Autowired
StringRedisTemplate redisTemplate;
//点赞
@PostMapping("like")
public Result like(@RequestBody LikeArgu likeArgu) {
String key1 = "likes:" + likeArgu.getT_id();
String key2 = "dislikes:" + likeArgu.getT_id();
//添加点赞记录
redisTemplate.opsForSet().add(key1, likeArgu.getU_id());
//如果该用户有点踩的话,把踩取消
redisTemplate.opsForSet().remove(key2, likeArgu.getU_id());
return Result.success();
}
//取消点赞
@PostMapping("unlike")
public Result unlike(@RequestBody LikeArgu likeArgu) {
String key = "likes:" + likeArgu.getT_id();
redisTemplate.opsForSet().remove(key, likeArgu.getU_id());
return Result.success();
}
//检查是否点赞,u_id为用户id, t_id为题目id
@GetMapping("isLiked")
public Result<Boolean> isLiked(@RequestParam("u_id") String u_id, @RequestParam("t_id") Integer t_id) {
String key = "likes:" + t_id;
return Result.success("请求成功", redisTemplate.opsForSet().isMember(key, u_id));
}
//返回点赞总数,t_id为题目id
@GetMapping("likeCount")
public Result<Long> getLikeCount(@RequestParam("t_id") Integer t_id) {
String key = "likes:" + t_id;
return Result.success("请求成功", redisTemplate.opsForSet().size(key));
}
}
点踩控制类
@RestController
@CrossOrigin
@RequestMapping("dislike")
public class DisLikeController {
@Autowired
StringRedisTemplate redisTemplate;
//点踩
@PostMapping("dislike")
public Result dislike(@RequestBody LikeArgu likeArgu) {
String key1 = "dislikes:" + likeArgu.getT_id();
String key2 = "likes:" + likeArgu.getT_id();
//添加点踩记录
redisTemplate.opsForSet().add(key1, likeArgu.getU_id());
//如果该用户有点赞的话,把赞取消
redisTemplate.opsForSet().remove(key2, likeArgu.getU_id());
return Result.success();
}
//取消点踩
@PostMapping("undislike")
public Result undislike(@RequestBody LikeArgu likeArgu) {
String key = "dislikes:" + likeArgu.getT_id();
redisTemplate.opsForSet().remove(key, likeArgu.getU_id());
return Result.success();
}
//检查是否点踩,u_id为用户id, t_id为题目id
@GetMapping("isDisliked")
public Result<Boolean> isDisliked(@RequestParam("u_id") String u_id, @RequestParam("t_id") Integer t_id) {
String key = "dislikes:" + t_id;
return Result.success("请求成功", redisTemplate.opsForSet().isMember(key, u_id));
}
//返回点踩总数,t_id为题目id
@GetMapping("dislikeCount")
public Result<Long> getDislikeCount(@RequestParam("t_id") Integer t_id) {
String key = "dislikes:" + t_id;
return Result.success("请求成功", redisTemplate.opsForSet().size(key));
}
}
点赞点踩参数类
public class LikeArgu {
String u_id;
Integer t_id;
public String getU_id() {
return u_id;
}
public void setU_id(String u_id) {
this.u_id = u_id;
}
public Integer getT_id() {
return t_id;
}
public void setT_id(Integer t_id) {
this.t_id = t_id;
}
}
响应实体类
public class Result<T> {
private Integer code;
private String msg;
private T data;
public static Result success() {
return new Result(200, "请求成功", null);
}
public static Result success(String msg) {
return new Result(200, msg, null);
}
public static <T> Result<T> success(String msg, T data) {
return new Result(200, msg, data);
}
public static Result error() {
return new Result(500, "请求失败", null);
}
public static Result error(String msg) {
return new Result(500, msg, null);
}
public static Result error(Integer code, String msg) {
return new Result(code, msg, null);
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
问题
在对StringRedisTemplate类进行依赖注入时出现的报错问题
Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'redisTemplate' is expected to be of type 'org.springframework.data.redis.core.StringRedisTemplate' but was actually of type 'org.springframework.data.redis.core.RedisTemplate'
具体问题是依赖注入的类型不对,它把RedisTemplate注入到StringRedisTemplate类型上了,所以导致了程序报错。
具体报错的代码为
@Resource
StringRedisTemplate redisTemplate;
具体原因和解决过程
使用redis来优化mysql能带来效率上的很大提升,但直接使用redis会出现一些问题,比如redis的持久化问题,以及redis的内存不足问题,在实际项目中往往还是redis+mysql来实现点赞功能,在redis中存储热门文章的点赞信息,前端需要点赞信息时首先去redis中查找,如果未找到则去mysql数据库中查询,并将数据缓存到redis中,并定期将redis数据库中的数据刷新到mysql中,因此,我还有许多东西需要学习,希望自己能继续努力。