3.20显示评论

上节课讲了事务管理,本节对其进行应用。
在这里插入图片描述
首先对数据库内的属性进行介绍

在这里插入图片描述
我们发布评论,可以对帖子(entity_type为1),也可以针对帖子内部的评论(entity_type为2),所以评论的目标是有变化的。

entity_id是指这个类型,是哪个具体的目标

要用一套业务解决所有评论的问题。

评论是有指向性的,用target_id记录回复指向的人。
在这里插入图片描述
在entity下新建实体类 Comment

package com.nowcoder.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;

    
    //后面get set方法是自动做好的
    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 +
                '}';
    }
}

接下来开发数据访问组件,mapper

在dao下新建接口
因为某个帖子评论会很多很多,所以要进行分页查询功能,

package com.nowcoder.community.dao;

import com.nowcoder.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);//根据Entity来查。offset limit是和分页有关的

    int selectCountByEntity(int entityType, int entityId);

    int insertComment(Comment comment);

}
接下来实现这个接口
新建 comment-mapper.html

<?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.community.dao.CommentMapper"><!-- 与CommentMapper做匹配 -->

    <sql id="selectFields">
        id, user_id, entity_type, entity_id, target_id, content, status, create_time
    </sql>

    <sql id="insertFields">
        user_id, entity_type, entity_id, target_id, content, status, create_time
    </sql>

    <select id="selectCommentsByEntity" resultType="Comment"><!--实现查询某一页数据的语句--><!-- 返回的是Comment集合-->
        select <include refid="selectFields"></include>
        from comment  <!--从comment中-->
        where status = 0<!--条件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) <!--id条数-->
        from comment
        where status = 0
        and entity_type = #{entityType}
        and entity_id = #{entityId}
    </select>

接下来写 业务层CommentService

@Service
public class CommentService implements CommunityConstant {
@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);
}

接下来处理 表现层

一个是controlller处理对应请求,在DiscussPostController中进行修改

@Autowired
private CommentService commentService;
@RequestMapping(path = "/detail/{discussPostId}", method = RequestMethod.GET)//声明路径。该方法要返回的是模板,即 discussdetail.html。所以不需要写ResponseBody
public String getDiscussPost(@PathVariable("discussPostId") int discussPostId, Model model, Page page) {//返回String是模板路径。page接收整理分页条件

    DiscussPost post = discussPostService.findDiscussPostById(discussPostId);// 查询帖子
    model.addAttribute("post", post);//传给模板
    // 作者(要传回去的是头像和用户名字,而不是UserId)
    User user = userService.findUserById(post.getUserId());
    model.addAttribute("user", user);

    // 评论分页信息
    page.setLimit(5);//每页显示5条评论
    page.setPath("/discuss/detail/" + discussPostId);//设置路径,要加动态的帖子id discussPostId
    page.setRows(post.getCommentCount());//一共多少条评论数据,以算出总的页数

    //名词解析:
    // 评论: 给帖子的评论
    // 回复: 给评论的评论

    // 评论列表
    List<Comment> commentList = commentService.findCommentsByEntity(//分页查询得到一个集合commentList,是当前帖子所有评论
            ENTITY_TYPE_POST, post.getId(), page.getOffset(), page.getLimit());//ENTITY_TYPE_POST是CommunityConstant中的常量

    // 评论VO列表(VO即显示对象)
    List<Map<String, Object>> commentVoList = new ArrayList<>();//用map封装要展示的数据  Vo=visual object要显示的对象
    if (commentList != null) {
        for (Comment comment : commentList) {//遍历集合,每次遍历得到一个comment

            Map<String, Object> commentVo = new HashMap<>();//新建一个map,名字commentVo
            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);//ENTITY_TYPE_COMMENT是CommunityConstant中的常量
            // 回复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());//回复目标。TargetId只在回复里,不会在评论。target = reply.getTargetId() == 0如果为真,则表示没有目标,如果有目标,返回目标用户target
                    replyVo.put("target", target);

                    replyVoList.add(replyVo);//放入集合
                }
            }
            commentVo.put("replys", replyVoList);//commentVo是唯一要传给其他程序的。commentVo包含了回复,评论的列表性数据。

因为public class DiscussPostController implements CommunityConstant {
所以在CommunityConstant中添加

/**
 * 实体类型: 帖子
 */
int ENTITY_TYPE_POST = 1;

/**
 * 实体类型: 评论
 */
int ENTITY_TYPE_COMMENT = 2;

为了显示 赞和回复的数目,需要在DiscussPostController中添加:

// 回复数量
int replyCount = commentService.findCommentCount(ENTITY_TYPE_COMMENT, comment.getId());
commentVo.put("replyCount", replyCount);//记录查询结果
commentVoList.add(commentVo);
model.addAttribute("comments", commentVoList);

在这里插入图片描述
在index.html中,

<li class="d-inline ml-2">回帖 <span th:text="${map.post.commentCount}">7</span></li><!-- map.post取到帖子-->

有两种情况,
用户名:内容
有目标的时候:谁回复给谁。
在这里插入图片描述

<span th:if="${rvo.target==null}"><!-- 如果target为空-->
				<b class="text-info" th:text="${rvo.user.username}">寒江雪</b>:&nbsp;&nbsp;
			</span>
			<span th:if="${rvo.target!=null}">
				<i class="text-info" th:text="${rvo.user.username}">Sissi</i> 回复<!-- 如果target不为空。Sissi 回复寒江雪:-->
				<b class="text-info" th:text="${rvo.target.username}">寒江雪</b>:&nbsp;&nbsp;
			</span>
<span th:utext="${rvo.reply.content}">这个是直播时间哈,觉得晚的话可以直接看之前的完整录播的~</span><!-- 回复内容 -->

另一个是 展示数据的页面

点击回复会出现这样一个框
在这里插入图片描述
discussdetail.html 代码如下157行

<li class="d-inline ml-2"><a th:href="|#huifu-${rvoStat.count}|" data-toggle="collapse" class="text-primary">回复</a></li>
					</ul>
					<div th:id="|huifu-${rvoStat.count}|" class="mt-4 collapse"><!-- 动态的生成id --><!-- 双竖线就是 常量+变量。--> <!-- 这样每个id就是hiufu-1,hiufu-2 ,和上两行的数据匹配-->

测试:
访问首页
在这里插入图片描述
可以看到回帖数量都变了,而不是固定的值
在这里插入图片描述
在这里插入图片描述
且每页显示都是五条评论。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值