创建表的实体类型,在 entity 包下创建 Comment 的实体类:
package com.example.demo.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 :
package com.example.demo.dao;
import com.example.demo.entity.Comment;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface CommentMapper {
List selectCommentsByEntity(int entityType, int entityId, int offset, int limit);
int selectCountByEntity(int entityType, int entityId);
}
在 resources 资源文件下 mapper 包下创建 discusspost-mapper.xml 写实现方法 :
id, user_id, entity_type, entity_id, target_id, content, status, create_time
在 service 包下新建业务组件 CommentService 类:
package com.example.demo.service;
import com.example.demo.dao.CommentMapper;
import com.example.demo.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 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);
}
}
在 controller 包下的 DiscussPostController 类( 查询帖子详情数据的方法)中 查询请求方法 补充:
/**
* 实体类型: 帖子
*/
int ENTITY_TYPE_POST = 1;
/**
* 实体类型: 评论
*/
int ENTITY_TYPE_COMMENT = 2;
@Autowired
private CommentService commentService;、
//查询请求方法
@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);
//第一种方法:在查询的时候使用关联查询 。优点:查询快;缺点:可能存在冗余、耦合
//第二种方法:先查出帖子数据,根据 id 调用 Userservice 查询 User,再通过 Model 将 User 发送给 模板,
// 这样模板得到了帖子,也得到了模板。优点:查询两次,没有冗余;缺点:查询慢
//在这里使用第二种情况,查询慢可以使用 Redis 来优化
// 作者
User user = userService.findUserById(post.getUserId());
// 把作者传给模板
model.addAttribute("user", user);
//评论分页信息
page.setLimit(5);//每页5个评论
page.setPath("discuss/detail/" + discussPostId);//访问路径
page.setRows(post.getCommentCount());//总数
// 评论: 给帖子的评论
// 回复: 给评论的评论
// 评论列表——发布帖子的评论列表
//分页查询,调用 commentService,首先查询帖子数据(帖子实体类型、id、分页条件)得到一个集合(得到当前帖子的所有评论)
List commentList = commentService.findCommentsByEntity(
ENTITY_TYPE_POST, post.getId(), page.getOffset(), page.getLimit());
//评论VO列表——创建一个集合,对展示的数据进行统一封装
List
在 dao 包下的 CommentMapper 中新增 添加评论 的方法:
//添加评论
int insertComment(Comment comment);
在 配置文件 comment-mapper.xml 中实现 sql:
user_id, entity_type, entity_id, target_id, content, status, create_time
insert into comment( )
values(#{userId},#{entityType},#{entityId},#{targetId},#{content},#{status},#{createTime})
增加评论之后更新帖子数量,在 DiscussPostMapper.java 中新增方法:
//更新帖子数量
int updateCommentCount(int id, int commentCount);
打开接口的配置文件 discusspost-mapper.xml 实现 sql:
update discuss_post set comment_count = #{commentCount} where id = #{id}
在 service 包下的 DiscussPostService(帖子业务组件)中增加更新评论数量:
//更新评论数量
public int updateCommentCount(int id, int commentCount) {
return discussPostMapper.updateCommentCount(id, commentCount);
}
在 CommentService(显示评论的业务方法) 中处理增加评论业务:
@Autowired
private SensitiveFilter sensitiveFilter;
@Autowired
private DiscussPostService discussPostService;
//增加评论的方法
@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
public int addComment(Comment comment) {
if (comment == null) {
throw new IllegalArgumentException("参数不能为空");
}
//添加评论:过滤标签和敏感词
comment.setContent(HtmlUtils.htmlEscape(comment.getContent()));
comment.setContent(sensitiveFilter.filter(comment.getContent()));
int rows = commentMapper.insertComment(comment);
//更新帖子评论数量
//判断实体类型是否是帖子,实现 CommunityConstant 接口,在查找评论数量;
//最后更新到帖子表中(根据帖子 id更新),需要注入 DiscussPostService
if (comment.getEntityType() == ENTITY_TYPE_POST) {
int count = commentMapper.selectCountByEntity(comment.getEntityType(), comment.getEntityId());
discussPostService.updateCommentCount(comment.getEntityId(), count);
}
return rows;
}
在 controller 包下新建 CommentController (处理增加评论的请求)类
package com.example.demo.controller;
import com.example.demo.entity.Comment;
import com.example.demo.service.CommentService;
import com.example.demo.util.HostHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import java.util.Date;
/**
* 处理增加评论的请求
*/
@Controller
@RequestMapping("/comment")
public class CommentController {
@Autowired
private CommentService commentService;
@Autowired
private HostHolder hostHolder;
@RequestMapping(path = "/add/{discussPostId}", method = RequestMethod.POST)
//通过 @PathVariable 得到帖子 id 参数,(传入提交内容、id、评论类型,声明实体类 Comment)
public String addComment(@PathVariable("discussPostId") int discussPostId, Comment comment) {
comment.setUserId(hostHolder.getUser().getId());
comment.setStatus(0);
comment.setCreateTime(new Date());
commentService.addComment(comment);
return "redirect:/discuss/detail/" + discussPostId;
}
}
前端页面 discuss-detail.html 中的回帖:
30条回帖