项目持续更新中:
目录
在我们的页面中间有一个评论的图标,我们可以点击一些
这里会有一个弹出框
点一下就能发送
我们首先要做的就是创建评论,发布评论。先创建好我们基础的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中改为
实现了评论的发表和评论数的展示,当我们进入评论页面时,评论记录应该在这里进行一个展示:
这里会涉及到查询,就需要用到我们两个表的关联:
但是我们这里会涉及到当前用户和回复用户,当前评论和回复评论,所以其实是四表关联的一个查询关系
先写一个自定义的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脚本查询变成三表或者两表查询,又或者说我们能不能不使用数据库,使用别的手段(中间件)来实现呢?