1. 开发思路
①数据层:
- 根据实体查询一页评论数据;
- 根据实体查询评论的数量。
②业务层:
- 处理查询评论的业务;
- 处理查询评论数量的业务。
③表现层:
- 显示帖子详情数据时,同时显示该帖子所有的评论数据。
2. 创建评论表的实体类
在entity包下新建实体类:Comment,对应评论的表。
package com.nowcoder.mycommunity.entity;
import java.util.Date;
//对应于【评论】表
public class Comment {
private int id;
private int userId;
private int entityType; //评论类型
private int entityId; //当前类型中,排下来的id
private int targetId; //回复的人
private String content;
private int status;
private Date createTime;
// get()、set()
// toString()
}
3. 数据层
①创建CommentMapper
在dao包下,创建接口CommentMapper,用来处理评论表的增删改查。
由于涉及到分页,需要用到两个方法:查询某页有多少数据、查询一共有多少条数据
package com.nowcoder.mycommunity.dao;
import com.nowcoder.mycommunity.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);
}
②Mapper接口对应的XML文件
在resources.mapper下创建comment-mapper.xml,用来实现上面接口中的SQL语句。
<?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.nowcoder.mycommunity.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.nowcoder.mycommunity.service;
import com.nowcoder.mycommunity.dao.CommentMapper;
import com.nowcoder.mycommunity.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中添加方法:
@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); //向VO中添加评论
commentVo.put("user", userService.findUserById(comment.getUserId())); //向VO中添加评论作者
//评论的回复:不分页
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";
}
注:由于用到新的常量,在util.CommunityConstant中添加:
//帖子的实体类型
int ENTITY_TYPE_POST = 1;
//评论的实体类型
int ENTITY_TYPE_COMMENT = 2;