项目持续更新中:
目录
用户发表评论
在我们的页面中间有一个评论的图标,我们可以点击一些
这里会有一个弹出框
点一下就能发送
我们首先要做的就是创建评论,发布评论。先创建好我们基础的controller:
这里我们先不进行编写,编写要查看前端路由
我们提前准备了一个CommentBO对象
这里的fatherCommentId指当前你发表了一条评论,其他用户是可以回复你,你自己的记录就会成为父记录
commentUserId是指当前登录者留言的用户id
我们先来创建service,需要注意我们在创建评论时,也是基于单表的一条记录报存,我们不需要自定义mapper,使用通用mapper:
接着实现我们的service,
public class CommentServiceImpl extends BaseInfoProperties implements CommentService {
@Autowired
private CommentMapper commentMapper;
@Autowired
private Sid sid;
@Override
public void createComment(CommentBO commentBO) {
String commentId = sid.nextShort();
Comment comment = new Comment();
comment.setId(commentId);
comment.setVlogId(commentBO.getVlogId());
comment.setVlogerId(commentBO.getVlogerId());
comment.setCommentUserId(commentBO.getCommentUserId());
comment.setFatherCommentId(commentBO.getFatherCommentId());
comment.setContent(commentBO.getContent());
comment.setLikeCounts(0);
comment.setCreateTime(new Date());
commentMapper.insert(comment);
}
}
注:我们这里评论点赞数默认为0。
接下来还需要添加一个很重要的操作,评论的点赞数需要存在redis中
打开前端,查看路由:
注:这里应该改为POST
前端在执行完毕之后,会得到一个新的记录。
我们在评论发表之后,用户考虑不一定会去刷新评论,我们不去数据库查询最新的评论,而是把用户发表的最新评论放到第一个位置,等到它下次进入才会做一个刷新,分页
在后端需要把一个最新的记录返回给前端做处理,这时候我们只需要再次构建一个VO
这里我们要修改一下返回类型
@Override
public CommentVO createComment(CommentBO commentBO) {
String commentId = sid.nextShort();
Comment comment = new Comment();
comment.setId(commentId);
comment.setVlogId(commentBO.getVlogId());
comment.setVlogerId(commentBO.getVlogerId());
comment.setCommentUserId(commentBO.getCommentUserId());
comment.setFatherCommentId(commentBO.getFatherCommentId());
comment.setContent(commentBO.getContent());
comment.setLikeCounts(0);
comment.setCreateTime(new Date());
commentMapper.insert(comment);
//redis操作放在service中,评论总数的累加
redis.increment(REDIS_VLOG_COMMENT_COUNTS+":"+commentBO.getVlogId(),1);
//留言后的最新评论需要返回给前端进行展示
CommentVO commentVO = new CommentVO();
BeanUtils.copyProperties(comment,commentVO);
return commentVO;
}
随后就能在Controller中实现
Meavn中install一下,重启,测试:
前端在这里会做一个判断是不是作者,如果是作者会在这里显示标记
我回复我自己:
这里评论成功了。
因为我们这里没有做查询,所以再一次关闭进入不会显示。
评论总数的显示
在主页中,评论过后,这里应该有一个评论数的累加和展现
打开我们的前端:
接着写我们的controller:
@GetMapping("counts")
public Object counts(@RequestParam String vlogId){
String countsStr = redis.get(REDIS_VLOG_COMMENT_COUNTS+":"+ vlogId);
if(StringUtils.isBlank(countsStr)){
countsStr = "0";
}
return GraceJSONResult.ok(Integer.valueOf(countsStr));
}
}
重启测试:
发表之后,这里评论数显示的是4条
前端数字总数的优雅展示
我们找到在redis中的记录
这里现在显示的评论数为4
我们修改成900,保存,这里没有问题
但是如果我们改成90w,这里显有点不太雅观。我们可以对它进行一定的优化,超过一千写成1k
超过一万,写1w
这里我们在前端处理
然后重新运行前端的源码,回到我们的后端:
我们在redis中改为
查询评论列表的sql脚本
实现了评论的发表和评论数的展示,当我们进入评论页面时,评论记录应该在这里进行一个展示:
这里会涉及到查询,就需要用到我们两个表的关联:
但是我们这里会涉及到当前用户和回复用户,当前评论和回复评论,所以其实是四表关联的一个查询关系
先写一个自定义的Mapper:
接着完成我们的sql语句
``这个符号代表除去关键字
<mapper namespace="com.imooc.mapper.CommentMapperCustom" >
<select id="getCommentList" parameterType="map" resultType="com.imooc.vo.CommentVO">
SELECT
c.id as commentId,
c.vlog_id as vlogId,
u.id as vlogerId,
u.nickname as commentUserNickname,
u.face as commentUserFace,
c.father_comment_id as fatherCommentId,
c.comment_user_id as commentUserId,
c.content as content,
c.like_counts as likeCounts,
fu.nickname as replyedUserNickname,
c.create_time as createTime
FROM
`comment` as c
LEFT JOIN
users as u
ON
c.comment_user_id = u.id
LEFT JOIN
`comment` as fc
ON
c.father_comment_id = fc.id
LEFT JOIN
users as fu
ON
fc.comment_user_id = fu.id
WHERE
c.vlog_id = #{paramMap.vlogId}
ORDER BY
c.like_counts DESC,
c.create_time DESC
</select>
</mapper>
这里的逻辑关系应该清除
思考:阿里的规范明确规定不能超过三表关联,这里达到了四张表,我们应该如何优化呢,使得SQL脚本查询变成三表或者两表查询,又或者说我们能不能不使用数据库,使用别的手段(中间件)来实现呢?