- 数据层
- 根据实体查询一页评论数据。
- 根据实体查询评论的数量。
- 业务层
- 处理查询评论的业务。 处理查询评论数量的业务。
- 表现层
- 显示帖子详情数据时, 同时显示该帖子所有的评论数据。
显示评论
这个功能是一个比较常规的功能,按照常规流程,数据层,业务层和表现层进行开发。
效果图
数据库
数据库的解释:user_id对应的是发评论的用户,entity_type是指评论的类型,目前我们打算开发论坛部分,那么就有两种类型,对帖子的评论和对评论的评论,为了方便区分,对评论的评论我们成为回复,entity_id对应回复的实体的id,target_id也就是回复的对象,这个主要是在回复的时候需要显示回复的谁
数据层
首先是对照数据库写comment实体类
package com.neu.langsam.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;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public int getEntityType() {
return entityType;
}
public void setEntityType(int entityType) {
this.entityType = entityType;
}
public int getEntityId() {
return entityId;
}
public void setEntityId(int entityId) {
this.entityId = entityId;
}
public int getTargetId() {
return targetId;
}
public void setTargetId(int targetId) {
this.targetId = targetId;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
@Override
public String toString() {
return "Comment{" +
"id=" + id +
", userId=" + userId +
", entityType=" + entityType +
", entityId=" + entityId +
", targetId=" + targetId +
", content='" + content + '\'' +
", status=" + status +
", createTime=" + createTime +
'}';
}
}
然后再dao包下写commentMapper,主要有两个方法,一个是查询评论,一个是查询评论数量。查询评论 这里也需要用到分页查询,用了offset和limit。
package com.neu.langsam.community.dao;
import com.neu.langsam.community.entity.Comment;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import java.util.List;
@Mapper
@Repository
public interface CommentMapper {
List<Comment> selectCommentsByEntity(int entityType,int entityId,int offset,int limit);
int selectCountByEntity(int entityType,int entityId);
}
然后就是再mapper目录下写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.neu.langsam.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>
业务层
业务层也比较简单,没有什么需要处理的,直接返回查询结果
package com.neu.langsam.community.service;
import com.neu.langsam.community.dao.CommentMapper;
import com.neu.langsam.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);
}
}
表现层
评论是显示在帖子详情页面,所以改造DiscussPostController的getDiscussPost方法。在CommunityConstant里加两个常量,用来表示评论的状态。
- 之前这个方法返回了帖子和作者的数据,因为评论需要分页,所以传入page对象。
- 对page对象进行配置,一页显示5条,page的路径和总的评论数
- 首先用上面写的方法查询评论,放到list里,然后还需要进行一些处理。查询到的评论里只有user_id,没有用户名,同时评论下还有回复。
- VO代表显示对象,用来显示在页面上的对象。
- 整个逻辑就是查出当前帖子下的所有评论,遍历所有评论,处理用户名等信息,查询评论下的回复,遍历每个回复,处理用户名等信息。
/**
* 实体类型:帖子
*/
int ENTITY_TYPE_POST = 1;
/**
* 实体类型:评论
*/
int ENTITY_TYPE_COMMENT = 2;
@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";
}