1.首先进行建表
大部分点赞都是文章,帖子,或者商品的点赞,然后登录用户进行点赞,创建表的话需要文章,帖子,或者商品的id和用户的id,我这里是文章postId和userId
2.接下来就是代码层面的实现
controller层(PostThumbAddRequest中放的是文章id)
@PostMapping("/")
public BaseResponse<Integer> doThumb(@RequestBody PostThumbAddRequest postThumbAddRequest,
HttpServletRequest request) {
if (postThumbAddRequest == null || postThumbAddRequest.getPostId() <= 0) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
// 登录才能点赞
final User loginUser = userService.getLoginUser(request);
long postId = postThumbAddRequest.getPostId();
int result = postThumbService.doPostThumb(postId, loginUser);
return ResultUtils.success(result);
}
service层
int doPostThumb(long postId, User loginUser);
serviceImpl层(用户串行点赞必须加锁)
@Override
public int doPostThumb(long postId, User loginUser) {
// 判断实体是否存在,根据类别获取实体
Post post = postService.getById(postId);
if (post == null) {
throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
}
// 是否已点赞
long userId = loginUser.getId();
// 每个用户串行点赞
// 锁必须要包裹住事务方法
//在同一个类中,非事务方法A调用事务方法B,事务失效,得采用AopContext.currentProxy().xx()来进行调用,事务才能生效。
PostThumbService postThumbService = (PostThumbService) AopContext.currentProxy();
synchronized (String.valueOf(userId).intern()) {
return postThumbService.doPostThumbInner(userId, postId);
}
}
doPostThumbInner是对数据库进行操作的,实现如下
int doPostThumbInner(long userId, long postId);
封装了事务的方法,出现错误立即回滚。
大概逻辑就是首先判断首先是否已经进行过点赞,如果已经点赞,当用户在进行点赞时,会取消点赞,首先移除点赞表里的信息,如果移除成功,将post里的点赞数进行更新,点赞数必须大于0才能进行减一操作,修改成功返回-1,失败返回0。如果用户未进行点赞更新post里的点赞数,点赞数进行加一操作
@Override
@Transactional(rollbackFor = Exception.class)
public int doPostThumbInner(long userId, long postId) {
PostThumb postThumb = new PostThumb();
postThumb.setUserId(userId);
postThumb.setPostId(postId);
QueryWrapper<PostThumb> thumbQueryWrapper = new QueryWrapper<>(postThumb);
PostThumb oldPostThumb = this.getOne(thumbQueryWrapper);
boolean result;
// 已点赞
if (oldPostThumb != null) {
result = this.remove(thumbQueryWrapper);
if (result) {
// 点赞数 - 1
result = postService.update()
.eq("id", postId)
//点赞数大于0
.gt("thumbNum", 0)
.setSql("thumbNum = thumbNum - 1")
.update();
return result ? -1 : 0;
} else {
throw new BusinessException(ErrorCode.SYSTEM_ERROR);
}
} else {
// 未点赞
result = this.save(postThumb);
if (result) {
// 点赞数 + 1
result = postService.update()
.eq("id", postId)
.setSql("thumbNum = thumbNum + 1")
.update();
//1为ture,0为false,如果更新成功返回1,失败返回0
return result ? 1 : 0;
} else {
throw new BusinessException(ErrorCode.SYSTEM_ERROR);
}
}
}
好了,点赞模块的代码就到这了