显示评论
开发安排:先根据数据库中已有的数据实现显示评论功能,再实现添加评论功能。
1.util包
CommunityConstant类中添加实体类型: 帖子,实体类型: 评论两个字段。
package com.gerrard.community.util;
public interface CommunityConstant {
/**
* 激活成功
*/
int ACTIVATION_SUCCESS = 0;
/**
* 重复激活
*/
int ACTIVATION_REPEAT = 1;
/**
* 激活失败
*/
int ACTIVATION_FAILURE = 2;
/**
* 默认状态的登录凭证的超时时间
*/
int DEFAULT_EXPIRED_SECONDS = 3600 * 12;
/**
* 记住状态的登录凭证超时时间
*/
int REMEMBER_EXPIRED_SECONDS = 3600 * 24 * 100;
/**
* 实体类型: 帖子
*/
int ENTITY_TYPE_POST = 1;
/**
* 实体类型: 评论
*/
int ENTITY_TYPE_COMMENT = 2;
}
2.entity包
在entity包中添加Comment类,与comment数据库中的各个字段对应。
package com.gerrard.community.entity;
import java.util.Date;
public class Comment {
private int id;
private int userId;
private int entityType;
private int entityId;
private int targetId;
private String content;
private int status;
private Date createTime;
}
comment MySQL数据库:
3.dao层
添加CommentMapper类。
package com.gerrard.community.dao;
import com.gerrard.community.entity.Comment;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface CommentMapper {
List<Comment> selectCommentsByEntity(int entityType, int entityId, int offset, int limit);
int selectCountByEntity(int entityType, int entityId);
}
添加comment-mapper.xml。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gerrard.community.dao.CommentMapper">
<sql id="selectFields">
id, user_id, entity_type, entity_id, target_id, content, status, create_time
</sql>
<select id="selectCommentsByEntity" resultType="Comment">
select <include refid="selectFields"></include>
from comment
where status = 0
and entity_type = #{entityType}
and entity_id = #{entityId}
order by create_time asc
limit #{offset}, #{limit}
</select>
<select id="selectCountByEntity" resultType="int">
select count(id)
from comment
where status = 0
and entity_type = #{entityType}
and entity_id = #{entityId}
</select>
</mapper>
4.service层
添加CommentService类。
package com.gerrard.community.service;
import com.gerrard.community.dao.CommentMapper;
import com.gerrard.community.entity.Comment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class CommentService {
@Autowired
private CommentMapper commentMapper;
public List<Comment> findCommentsByEntity(int entityType, int entityId, int offset, int limit) {
return commentMapper.selectCommentsByEntity(entityType, entityId, offset, limit);
}
public int findCommentCount(int entityType, int entityId) {
return commentMapper.selectCountByEntity(entityType, entityId);
}
}
5.controller层
继续完善DiscussPostController类中的getDiscussedPost方法。
package com.gerrard.community.controller;
import com.gerrard.community.entity.Comment;
import com.gerrard.community.entity.DiscussPost;
import com.gerrard.community.entity.Page;
import com.gerrard.community.entity.User;
import com.gerrard.community.service.CommentService;
import com.gerrard.community.service.DiscussPostService;
import com.gerrard.community.service.UserService;
import com.gerrard.community.util.CommunityConstant;
import com.gerrard.community.util.CommunityUtil;
import com.gerrard.community.util.HostHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.*;
@Controller
@RequestMapping("/discuss")
public class DiscussPostController implements CommunityConstant {
@Autowired
private DiscussPostService discussPostService;
@Autowired
private HostHolder hostHolder;
@Autowired
private UserService userService;
@Autowired
private CommentService commentService;
@RequestMapping(path = "/add", method = RequestMethod.POST)
@ResponseBody
public String addDiscussPost(String title, String content) {
User user = hostHolder.getUser();
if (user == null) {
return CommunityUtil.getJSONString(403, "你还没有登录哦!");
}
DiscussPost post = new DiscussPost();
post.setUserId(user.getId());
post.setTitle(title);
post.setContent(content);
post.setCreateTime(new Date());
discussPostService.addDiscussPost(post);
// 报错的情况,将来统一处理.
return CommunityUtil.getJSONString(0, "发布成功!");
}
@RequestMapping(path = "/detail/{discussPostId}", method = RequestMethod.GET)
public String getDiscussPost(@PathVariable("discussPostId") int discussPostId, Model model, Page page) {
// 帖子
DiscussPost post = discussPostService.findDiscussPostById(discussPostId);
model.addAttribute("post", post);
// 作者
User user = userService.findUserById(post.getUserId());
model.addAttribute("user", user);
// 评论分页信息
page.setLimit(5);
page.setPath("/discuss/detail/" + discussPostId);
page.setRows(post.getCommentCount());
// 评论: 给帖子的评论
// 回复: 给评论的评论
// 评论列表
List<Comment> commentList = commentService.findCommentsByEntity(
ENTITY_TYPE_POST, post.getId(), page.getOffset(), page.getLimit());
// 评论VO列表
List<Map<String, Object>> commentVoList = new ArrayList<>();
if (commentList != null) {
for (Comment comment : commentList) {
// 数据增强
// 评论VO
Map<String, Object> commentVo = new HashMap<>();
// 评论
commentVo.put("comment", comment);
// 查询到评论的作者
commentVo.put("user", userService.findUserById(comment.getUserId()));
// 回复列表 复用查询评论与回复
List<Comment> replyList = commentService.findCommentsByEntity(
ENTITY_TYPE_COMMENT, comment.getId(), 0, Integer.MAX_VALUE);
// 回复VO列表
List<Map<String, Object>> replyVoList = new ArrayList<>();
if (replyList != null) {
for (Comment reply : replyList) {
Map<String, Object> replyVo = new HashMap<>();
// 回复
replyVo.put("reply", reply);
// 作者
replyVo.put("user", userService.findUserById(reply.getUserId()));
// 回复目标
User target = reply.getTargetId() == 0 ? null : userService.findUserById(reply.getTargetId());
replyVo.put("target", target);
replyVoList.add(replyVo);
}
}
commentVo.put("replys", replyVoList);
// 回复数量
int replyCount = commentService.findCommentCount(ENTITY_TYPE_COMMENT, comment.getId());
commentVo.put("replyCount", replyCount);
commentVoList.add(commentVo);
}
}
model.addAttribute("comments", commentVoList);
return "/site/discuss-detail";
}
}
评论按笔者的理解可以细分为三类:
第一类:针对帖子的评论;
第二类:针对评论的评论,但其targetId为0;
第三类:针对评论的评论,其targetId不为0。
如果不细分划分为两类即可:
第一类:针对帖子的评论;
第二类:针对评论的评论。
先从comment MySQL数据库中查到分页条件下,指定帖子的“针对帖子的评论”集合commentList,接着遍历commentList,对commentList中的Comment元素,进行数据增强,查到评论的作者,再查到评论附带的回复集合,回复的数量,添加到各自Map集合中。
查到评论附带的回复集合:先查到回复列表,再进行数据增强:遍历回复列表,添加回复作者实体,回复目标用户实体(如果target_id为0则目标用户实体为空)。
最后将查到的信息相应给前端,返回discuss-detail.html页面。
6.view层
index.html:
discuss-detail.html:(前端都是通过键访问,不管是modelAttribute还是HashMap中,还有变量名,.成员变量名称)
7.功能测试
8.事务理论知识
9.小问题
第二种装载方式,前端需要更改代码。
model.addAttribute("comment", postList);
modek,addAttribute("user",userList);
model.addAttribute("replys", replyList<HashMap>);
model.addAttribute("replyCount", replyCounts);
两种装载方式都是可以的。