这篇文章,我来介绍一下我的项目中的另外一个功能:显示评论和添加评论。
其实这两个功能都不怎么重要,我感觉最重要的应该是用户注册登录功能,这个也了解一下,知道这么一回事儿就好。
首先设计DAO层。
@Mapper
public interface CommentMapper {
List<Comment> selectCommentsByEntity(int entityType, int entityId, int offset, int limit);
//根据实体类型、实体ID以及分页偏移量和限制数量,查询对应实体的评论列表,并返回一个评论对象的列表
int selectCountByEntity(int entityType, int entityId);
//根据实体类型和实体ID,查询对应实体的评论数量,并返回结果
int insertComment(Comment comment);
//插入一条评论记录到数据库中,参数为一个评论对象
Comment selectCommentById(int id);
//根据评论ID,查询并返回对应的评论对象
}
这些方法用于对评论表进行常见的数据库操作,例如查询某个实体的评论列表、查询评论数量、插入评论以及根据评论ID查询评论详情。
再来设计service层。
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);
}
@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);
// 更新帖子评论数量
if (comment.getEntityType() == ENTITY_TYPE_POST) {
int count = commentMapper.selectCountByEntity(comment.getEntityType(), comment.getEntityId());
discussPostService.updateCommentCount(comment.getEntityId(), count);
}
return rows;
}
public Comment findCommentById(int id) {
return commentMapper.selectCommentById(id);
}
上面的代码是一个评论服务类,用于处理与评论相关的业务逻辑。
findCommentCount()
方法用于根据实体类型和实体ID,调用 commentMapper.selectCountByEntity()
方法查询对应实体的评论数量,并返回结果。
addComment()
方法用于添加一条评论。在方法中,首先对评论内容进行处理,使用 HtmlUtils.htmlEscape()
方法进行 HTML 转义,以防止 XSS 攻击,然后使用 sensitiveFilter.filter()
方法过滤敏感词。接下来调用 commentMapper.insertComment()
方法将评论插入到数据库中。
findCommentById()
方法用于根据评论ID查询对应的评论对象,调用 commentMapper.selectCommentById()
方法进行查询,并返回结果。
这些方法结合了评论数据库访问对象(DAO)的方法,处理评论的查询、添加和统计等业务逻辑,并且在添加评论时还会更新帖子的评论数量。
最后写controller层。
public String addComment(@PathVariable("discussPostId") int discussPostId, Comment comment) {
comment.setUserId(hostHolder.getUser().getId());
comment.setStatus(0);
comment.setCreateTime(new Date());
commentService.addComment(comment);
// 触发评论事件
Event event = new Event()
.setTopic(TOPIC_COMMENT)
.setUserId(hostHolder.getUser().getId())
.setEntityType(comment.getEntityType())
.setEntityId(comment.getEntityId())
.setData("postId", discussPostId);
if (comment.getEntityType() == ENTITY_TYPE_POST) {
DiscussPost target = discussPostService.findDiscussPostById(comment.getEntityId());
event.setEntityUserId(target.getUserId());
} else if (comment.getEntityType() == ENTITY_TYPE_COMMENT) {
Comment target = commentService.findCommentById(comment.getEntityId());
event.setEntityUserId(target.getUserId());
}
eventProducer.fireEvent(event);
if (comment.getEntityType() == ENTITY_TYPE_POST) {
// 触发发帖事件
event = new Event()
.setTopic(TOPIC_PUBLISH)
.setUserId(comment.getUserId())
.setEntityType(ENTITY_TYPE_POST)
.setEntityId(discussPostId);
eventProducer.fireEvent(event);
// 计算帖子分数
String redisKey = RedisKeyUtil.getPostScoreKey();
redisTemplate.opsForSet().add(redisKey, discussPostId);
}
return "redirect:/discuss/detail/" + discussPostId;
}
}
在方法体中,首先设置评论的用户ID为当前登录用户的ID,评论的状态为0(表示正常状态),创建时间为当前时间。然后调用 commentService.addComment()
方法将评论添加到数据库中。
接下来,根据评论的实体类型(帖子或评论),创建一个事件对象 event
,设置事件的相关属性,例如话题(topic)、用户ID、实体类型、实体ID等。如果评论的实体类型是帖子,则还会获取该帖子的作者ID,如果是评论,则获取评论的目标对象(评论的回复对象)的作者ID。
最后,返回一个重定向的视图,将页面重定向到帖子详情页,以展示添加评论后的页面效果。
这就是显示评论和添加评论的功能。简单了解一下既可!