不知道大家有没有遇到类似于微博这种需要实现评论和回复的项目,如图:

那么在面对这种需求的时候,先想想数据库该如何设计。针对这个模块,涉及到的对象有:用户、动态、评论和回复,由于用户表只需要在这里绑定一个主键ID作为外键,就暂时先不考虑用户表的设计。接下来就对动态、评论和回复来分别设计数据表

动态表:动态ID、用户ID、动态内容、动态图片、发布时间
评论表:评论ID、用户ID、动态ID、评论内容、评论时间
回复表:回复ID、用户ID、动态ID、评论ID、回复内容、回复时间

发现问题没有?评论表和回复表的字段几乎是一样的。我们可以这样理解:【评论是对动态进行评论,而回复是对评论进行评论】,说白了就是,回复也是评论,那么为什么还要单独建一张回复表呢?那么我们来优化一下

动态表:动态ID、用户ID、动态内容、动态图片、发布时间
评论表:评论ID、用户ID、动态ID、评论内容、评论时间、评论ID2

这个评论ID2是什么情况?其实是这样的,评论ID2存放的数据也是评论ID,它指明了当前这条数据是针对哪条评论进行评论的。好像还是有点绕,咱们来画个图捋一捋。

这样子看上去也许更容易理解一点……
接下来正式开始建表



其他表就不多说了,把这几个基本的表建好之后,手动加几条数据,然后拉到项目中去,那么问题又来了,数据该怎么查?有同学肯定想到了,那不是有个动态ID吗?我们可以根据动态ID,将该动态下的所有评论都查出来。既然想到了,我们就来试试。

 public List<Comment> findCommentList(int trendsid) {// TODO Auto-generated method stubList<Comment> list = null;try {String sql = "select comment.*,user.username from comment inner join user on comment.userid=user.userid"+" where trendsid = ? order by commentdate desc";//查询的SQL语句,通过时间进行排序con=DbUtil.getConnection();ps=con.prepareStatement(sql);ps.setInt(1, trendsid);rs=ps.executeQuery();list=JdbcHelper.getResult(rs, Comment.class);//jdbcHelper封装的工具类,通过反射获取返回结果集} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{DbUtil.close(con, ps, rs);//关闭连接}return list;//返回结果列表}

在Dao中写好查询方法,获取到数据库返回的结果集,接下来就是返回给servlet和jsp。servlet也就那样,就不截出来了,下面是jsp的代码

function findComment(){$.ajaxSettings.async=false;//取消异步$.getJSON("${ctx}/servlet/UserServlet?fun=findCommentList",{trendsid:trendsid},function(data){data=data[0];//console.log(data);if(data.length>0){$("#commentbox").empty();//清空html内容}$.each(data,function(i){//循环获取到每一条数据,使用append()方法将数据拼接到指定的html中$("#commentbox").append('<div class="comment" id="comment'+ data[i].commentid +'">'+'<span class="commentdate">'+data[i].commentdate+'</span>'+'<span class="user">'+data[i].username+'</span><span class="commenttext" οnclick="replyThis('+data[i].commentid+')">'+data[i].commenttext+'</span></div>');});};

到浏览器跑一下看看效果

数据是都查出来了,但好像有什么不对的地方,这样显示好像看不出来是谁在回复谁了。这个结果不尽人意啊,需要改善一下。我们再来分析一下评论表的结构,我们设计的评论表是一张递归表,上图的第三条评论的replyid为0,可以将它分为第一层的数据;第二条评论是针对第三条评论的回复,故评论三是评论二的上级,那么评论二可以分为第二层数据;以此类推,第一条评论可以分为第三层的数据……因此,我们可以先将第一层的数据查出来,追加到评论列表中,之后再根据它的主键ID去查询它下一层的评论数据。

 public List<Comment> findCommentList(int trendsid) {//Dao方法不变,只是在SQL语句中加了一个条件replyid=0 // TODO Auto-generated method stubList<Comment> list = null;try {String sql = "select comment.*,user.username from comment inner join user on comment.userid=user.userid"+" where trendsid = ? and replyid=0 and replyid=0 order by commentdate desc";//replyid=0 查询的是第一层的数据

接下来就是第二层评论的查询

 public List<Comment> findReoly(int commentid) {List<Comment> list = new ArrayList<Comment>();try {//因为要分别查出评论人和回复人的名字所以连的表有点多...//重点是comment表自连接,连接条件是c1的主键ID=c2的上级ID//最后根据传进来的上级ID作为查询条件String sql="SELECT c1.userid uid,u1.username uname,u2.username,c2.* FROM COMMENT c1 INNER JOIN COMMENT c2 ON c1.commentid=c2.replyid"+" INNER JOIN USER u1 ON c1.userid=u1.userid INNER JOIN USER u2 ON c2.userid=u2.userid"+" WHERE c1.commentid=? ORDER BY c2.commentdate DESC ";con=DbUtil.getConnection();ps=con.prepareStatement(findReoly);ps.setInt(1, commentid);rs=ps.executeQuery();list=JdbcHelper.getResult(rs, Comment.class);} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{DbUtil.close(con, ps, rs);}return list;}

由于评论不仅仅只有第二层,还有第三层第四层等等,所以我们需要一个递归,不停的遍历它的下一层,直到下一层没有数据为止。递归可以写在jsp页面或者servlet中,但是写在jsp页面上会造成页面不断提交,严重影响的查询的效率,所有我们将递归写在servlet中。

 Set<Comment> thisSet = new HashSet<Comment>();//在方法外声明一个set集合,用来存放查询结果public void findReoly(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException{thisSet.clear();//在请求进来的时候讲set集合清空int commentid = Integer.parseInt(request.getParameter("commentid"));Set<Comment> sets = findReolyOther(commentid);//调用递归方法JsonConfig jsonConfig = new JsonConfig();jsonConfig.registerJsonValueProcessor(java.util.Date.class, new DateJsonValueProcessor("yyyy-MM-dd HH:mm:ss"));JSONArray array = JSONArray.fromObject(sets, jsonConfig);JSONObject json = new JSONObject();json.put(0, array);response.getWriter().write(json.toString());//返回json格式的数据}public Set<Comment> findReolyOther(int commentid){//调用Dao的查询方法,若list.size()>0,也就是还有下一层数据,就进入循环List<Comment> list = userSer.findReoly(commentid);if(list.size()>0){for(int i=0;i<list.size();i++){thisSet.add(list.get(i));//将查询结果添加到set集合中int id = list.get(i).getCommentid();//获取到该结果中的commentid字段,作为条件来查询它的下一层数据findReolyOther(id);//递归}}return thisSet;//返回结果集}

请求接受的是页面传递过来的第一层评论的主键ID,然后将其下所有的相关评论返回给页面。

 //console.log(data[i].commentid);//还是在循环中,将第一层评论的主键ID依次传递$.getJSON("${ctx}/servlet/UserServlet?fun=findReoly",{commentid:data[i].commentid},function(msg){msg=msg[0];if(msg.length>0){for(var j=0;j<msg.length;j++){//console.log(msg[j]);//通过append()方法,将返回的结果追加到html中$("#comment"+data[i].commentid).append('<div class="reply" id="comment'+msg[j].commentid+'"><span class="user thisuser">'+msg[j].username+'</span> 回复 <span class="user">'+msg[j].uname+'</span>:'+'<span class="replytext" οnclick="replyRep('+msg[j].commentid+')">'+msg[j].commenttext+'</span></div>');};};});

大功告成!浏览器跑一下~

评论+回复的设计思路和实现相关推荐

  1. 文章评论回复的设计思路

    零.前言 之前做过一款小程序,其中包含用户发布动态.评论.回复评论的功能,当时不知道怎么设计,一直在网上百度也没有找到好的设计,现在把之前的设计思路放出来.如果你更好的设计思路,请在评论区放上文章链接 ...

  2. mysql 评论回复表设计_数据库设计——评论回复功能

    1.概述 评论功能已经成为APP和网站开发中的必备功能.本文主要介绍评论功能的数据库设计. 评论功能最主要的是发表评论和回复评论(删除功能在后台).评论功能的拓展功能体现有以下几方面: (1)单篇文章 ...

  3. mysql 评论回复表设计_【数据库】评论回复表设计

    一般系统发展到一定时候,就会需要加上评论功能.评论也会有很多形式,不同形式的评论展示表的设计也不一样.这里介绍几种比较常见的评论. 1.一问一答 张三:文章写的不错. 作者 回复 张三:谢谢你的认可 ...

  4. 网站点赞 评论 回复 数据库设计

    本文主要分享了我在设计评论模块中的一些心得,希望对读者有些许帮助. 关于这种常用功能,查了许多资料 又基于公司的业务场景 1.由用户发表作品  其他已注册用户 在浏览个用户发表的作品时可以进行 点赞 ...

  5. java评论回复表设计_评论回复功能数据表设计

    CREATE TABLE `comment` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `topic_id` int(10) unsigned ...

  6. 评论回复功能的设计与实现

    评论回复功能的数据库设计可以分开设计成两张表,评论表和回复表,也可以将其设计为一张表,我采用的是一张表 评论回复表的相关字段(我做的是商品goods下的评论回复) 字段解释: gc_id:评论回复表i ...

  7. mysql 评价表设计_来聊聊mysql单表评论系统怎么设计

    评论系统对于一个网站来说几乎是必不可少的,当然评论系统的设计也多种多样.一般情况下,评论数据表会和一个用户信息表结合使用,就是在评论表中记录的有用户id(例如user_id),然后查询评论数据的时候根 ...

  8. 百度评论中台的设计与探索

    导读:百度评论中台为百度系产品提供便利接入.持续稳定的评论能力,是百度社区氛围体系内最重要的基础能力之一,日均流量达到百亿规模,在业务不断发展过程中,百度评论中台实现了功能快速迭代.性能稳步提升,本文 ...

  9. 【项目实战】个人博客(SpringBoot,SSM,thymeleaf,Semantic UI)——从设计思路到部署一站式教学

    一.前言 1.项目背景 此项目并非原创,项目原型是李仁密老师的作品,具体的教学视频来自b站https://www.bilibili.com/video/BV1nE411r7TF,不过up主貌似也是搬运 ...

最新文章

  1. C语言:随笔5--指针1
  2. 2012年12月4期手机网页开发
  3. linux下备份mssql文件,linux服务器怎么定时备份mysql的sql文件数据
  4. python 代码-代码的重试机制(python简单实现)
  5. “达观杯”文本智能处理挑战赛,季军带你飞
  6. Centos7 虚拟机复制后网卡问题 Job for network.service failed
  7. 矩形法_字体设计 | 新手必学,超简单的矩形造字法!!
  8. php解密 码表,php拼音码表的生成
  9. java读取同包文件_Java实现从jar包中读取指定文件的方法
  10. javasript深度拷贝
  11. 电子邮件如何运行(MTA,MDA,MUA)
  12. JavaCV开发详解之27:使用javacv把视频切割成多个视频分片文件,以mp4为例,把视频切割成MP4分片文件
  13. web性能优化的一些方法
  14. ns3网络设置模块 PointToPoint
  15. 世界上最畅销的JSON和XML编辑器-Altova XMLSpy 2021版发布,升级版JSON Grid View归来!
  16. 背包问题之0-1背包算法详解
  17. Mind+实例1——智慧农场
  18. 如何培养孩子的金钱价值观
  19. 【NLP】Python NLTK 走进大秦帝国
  20. 代自序 财富寓言:羊、狼、狮子与大象(1)

热门文章

  1. Cloudcanal数据同步神器
  2. 【Linux常用服务器配置——NFS服务】
  3. 爬取企查查公司URL
  4. python pymysql模块下载_Python Pymysql模块
  5. Java 实现 LRU 算法
  6. killall 后面信号_killall 、kill 、pkill 命令区别
  7. gb编码转换utf8
  8. ArcGisPro脚本工具【0】——制作你的第一个脚本工具
  9. CSP题目:跳一跳小游戏
  10. 软件系统的哲学对于吸引追随者的重要性