评论+回复的设计思路和实现
不知道大家有没有遇到类似于微博这种需要实现评论和回复的项目,如图:
那么在面对这种需求的时候,先想想数据库该如何设计。针对这个模块,涉及到的对象有:用户、动态、评论和回复,由于用户表只需要在这里绑定一个主键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>');};};});
大功告成!浏览器跑一下~
评论+回复的设计思路和实现相关推荐
- 文章评论回复的设计思路
零.前言 之前做过一款小程序,其中包含用户发布动态.评论.回复评论的功能,当时不知道怎么设计,一直在网上百度也没有找到好的设计,现在把之前的设计思路放出来.如果你更好的设计思路,请在评论区放上文章链接 ...
- mysql 评论回复表设计_数据库设计——评论回复功能
1.概述 评论功能已经成为APP和网站开发中的必备功能.本文主要介绍评论功能的数据库设计. 评论功能最主要的是发表评论和回复评论(删除功能在后台).评论功能的拓展功能体现有以下几方面: (1)单篇文章 ...
- mysql 评论回复表设计_【数据库】评论回复表设计
一般系统发展到一定时候,就会需要加上评论功能.评论也会有很多形式,不同形式的评论展示表的设计也不一样.这里介绍几种比较常见的评论. 1.一问一答 张三:文章写的不错. 作者 回复 张三:谢谢你的认可 ...
- 网站点赞 评论 回复 数据库设计
本文主要分享了我在设计评论模块中的一些心得,希望对读者有些许帮助. 关于这种常用功能,查了许多资料 又基于公司的业务场景 1.由用户发表作品 其他已注册用户 在浏览个用户发表的作品时可以进行 点赞 ...
- java评论回复表设计_评论回复功能数据表设计
CREATE TABLE `comment` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `topic_id` int(10) unsigned ...
- 评论回复功能的设计与实现
评论回复功能的数据库设计可以分开设计成两张表,评论表和回复表,也可以将其设计为一张表,我采用的是一张表 评论回复表的相关字段(我做的是商品goods下的评论回复) 字段解释: gc_id:评论回复表i ...
- mysql 评价表设计_来聊聊mysql单表评论系统怎么设计
评论系统对于一个网站来说几乎是必不可少的,当然评论系统的设计也多种多样.一般情况下,评论数据表会和一个用户信息表结合使用,就是在评论表中记录的有用户id(例如user_id),然后查询评论数据的时候根 ...
- 百度评论中台的设计与探索
导读:百度评论中台为百度系产品提供便利接入.持续稳定的评论能力,是百度社区氛围体系内最重要的基础能力之一,日均流量达到百亿规模,在业务不断发展过程中,百度评论中台实现了功能快速迭代.性能稳步提升,本文 ...
- 【项目实战】个人博客(SpringBoot,SSM,thymeleaf,Semantic UI)——从设计思路到部署一站式教学
一.前言 1.项目背景 此项目并非原创,项目原型是李仁密老师的作品,具体的教学视频来自b站https://www.bilibili.com/video/BV1nE411r7TF,不过up主貌似也是搬运 ...
最新文章
- C语言:随笔5--指针1
- 2012年12月4期手机网页开发
- linux下备份mssql文件,linux服务器怎么定时备份mysql的sql文件数据
- python 代码-代码的重试机制(python简单实现)
- “达观杯”文本智能处理挑战赛,季军带你飞
- Centos7 虚拟机复制后网卡问题 Job for network.service failed
- 矩形法_字体设计 | 新手必学,超简单的矩形造字法!!
- php解密 码表,php拼音码表的生成
- java读取同包文件_Java实现从jar包中读取指定文件的方法
- javasript深度拷贝
- 电子邮件如何运行(MTA,MDA,MUA)
- JavaCV开发详解之27:使用javacv把视频切割成多个视频分片文件,以mp4为例,把视频切割成MP4分片文件
- web性能优化的一些方法
- ns3网络设置模块 PointToPoint
- 世界上最畅销的JSON和XML编辑器-Altova XMLSpy 2021版发布,升级版JSON Grid View归来!
- 背包问题之0-1背包算法详解
- Mind+实例1——智慧农场
- 如何培养孩子的金钱价值观
- 【NLP】Python NLTK 走进大秦帝国
- 代自序 财富寓言:羊、狼、狮子与大象(1)