前言

使用递归循环开发评论回复功能,适用于大部分的简单单体应用

评论功能或许是大多数的单体应用之中会用到的功能,我们会在自己所开发的项目之中进行集成该功能

大多数时候我们会将评论功能划分成以下几种:

单一型

嵌套型

两层型

一、分类方式

1、单一型

单一型评论方式就是日常论坛之中的盖楼的方式

用户只能根据所在的文章或者问题进行单一回复,评论之间没有互动

类似于问答形式。提出问题,然后回答,一对多关系。这些回答之间没有任何联系

2、嵌套型

嵌套型评论方式会对有回复的评论进行递归,会造成后端性能不佳,而且对于前端的展示也不是很友好

3、两层型

两层型评论方式就是除了一级评论之外,无论是对于该评论的回复还是对于回复的回复都统一在第二层

二、实现原理

就以最常见的博客来说,不同的分类方式实现原理不一样

1、单一型

我们只需要在评论的数据表格中添加博客id即可,查询出相对应的数据直接进行展示即可

create table `comment` (

`id` int(11) not null auto_increment comment '主键id',

`nickname` varchar(255) default null comment '评论者昵称',

`avatar` varchar(255) comment '评论头像',

`content` varchar(255) default null comment '评论的内容',

`blog_id` int(11) default null comment '评论的博客id',

primary key (`id`)

) comment '评论表';

在业务之中根据博客id查询出来,传递给前端展示出来即可

select * from comment where blog_id=#{blog_id}

2、嵌套型

嵌套型的评论方式所需要的数据结构是树状型的,评论多起来的话层级结构会变得很复杂,对于性能消耗也是很巨大,【不推荐】

实现原理为我们会在评论表之中添加一个【parent_id】字段,定义评论和回复为父子级的关系,评论为父级,回复为子级,默认为【-1】,表示为没有父级,

create table `comment` (

`id` int(11) not null auto_increment comment '主键id',

`nickname` varchar(255) default null comment '评论者昵称',

`avatar` varchar(255) comment '评论头像',

`content` varchar(255) default null comment '评论的内容',

`blog_id` int(11) default null comment '评论的博客id',

`parent_id` int(11) default '-1' comment '父级评论id',

primary key (`id`)

) comment '评论表';

需要使用递归和链表进行循环遍历插入回复

设计如下:

Content.java

private static final long serialVersionUID = 1L;

@ApiModelProperty(value = "主键id")

@TableId(value = "id", type = IdType.ASSIGN_ID)

private Integer id;

@ApiModelProperty(value = "用户昵称")

@TableField("nickname")

private String nickname;

@ApiModelProperty(value = "头像")

@TableField("avatar")

private String avatar;

@ApiModelProperty(value = "评论")

@TableField("comment")

private String comment;

@ApiModelProperty(value = "博客id ")

@TableField("blog_id")

private Integer blogId;

@ApiModelProperty(value = "回复评论id")

@TableField("parent_id")

private Integer parentId;

DTO设计

ContentDTO.java

@Data

@NoArgsConstructor

@AllArgsConstructor

@Accessors(chain = true)

@ApiModel(value = "评论模型")

@JsonIgnoreProperties(value = { "handler" })

public class ContentDTO {

private int id;

private String nickname;

private String content;

private List children;

}

使用mybatis做为持久层框架,编写sql查询语句进行嵌套查询,

select="com.zukxu.items.comment.mapper.ContentMapper.selectCommentById" column="{blogId=blog_id,parentId=comment_id}"

fetchType="lazy">

SELECT comment_id,nickname,content,blog_id,parent_id FROM blog WHERE blog_id = #{blogId} AND parent_id = #{parentId}

结果如下:

[

{

"id": "1309302063977304065",

"nickname": "1",

"content": "这次该可以了吧",

"children": [

{

"id": "1309319425866698753",

"nickname": "1",

"content": "好了?",

"children": []

}

]

},

{

"id": "1309341283121154994",

"nickname": "4",

"content": "为什么呢",

"children": [

{

"id": "1309373849414787073",

"nickname": "1",

"content": "好了?",

"children": []

},

{

"id": "1309308402422091778",

"nickname": "1",

"content": "可以了吧",

"children": []

},

{

"id": "1309373675783184385",

"nickname": "1",

"content": "好了?",

"children": [

{

"id": "1309373886580514817",

"nickname": "1",

"content": "???",

"children": []

}

]

}

]

}

]

结果会造成多重嵌套,不是很友好

3、两层型

比单一型多了互动的功能,比嵌套型更加简洁,方便操作管理

设计和嵌套型保持一致,只需要在查询出来数据之后对数据进行处理即可

将嵌套型转为两层型结构

处理每个父级评论的子级及其嵌套子级

public List findParent(List comments) {

for (CommentDTO comment : comments) {

// 防止checkForComodification(),而建立一个新集合

ArrayList fatherChildren = new ArrayList<>();

// 递归处理子级的回复,即回复内有回复

findChildren(comment, fatherChildren);

// 将递归处理后的集合放回父级的孩子中

comment.setChildren(fatherChildren);

}

return comments;

}

public void findChildren(CommentDTO parent, List fatherChildren) {

// 找出直接子级

List comments = parent.getChildren();

// 遍历直接子级的子级

for (CommentDTO comment : comments) {

// 若非空,则还有子级,递归

if (!comment.getChildren().isEmpty()) {

findChildren(comment, fatherChildren);

}

// 已经到了最底层的嵌套关系,将该回复放入新建立的集合

fatherChildren.add(comment);

// 容易忽略的地方:将相对底层的子级放入新建立的集合之后

// 则表示解除了嵌套关系,对应的其父级的子级应该设为空

comment.setChildren(new ArrayList<>());

}

}

}

最后的结果如下:

[

{

"id": "1309302063977304065",

"userId": "1",

"comment": "这次该可以了吧",

"children": [

{

"id": "1309319425866698753",

"userId": "1",

"comment": "好了?",

"children": []

}

]

},

{

"id": "1309341283121154994",

"userId": "4",

"comment": "为什么呢",

"children": [

{

"id": "1309373849414787073",

"userId": "1",

"comment": "好了?",

"children": []

},

{

"id": "1309308402422091778",

"userId": "1",

"comment": "可以了吧",

"children": []

},

{

"id": "1309373886580514817",

"userId": "1",

"comment": "???",

"children": []

},

{

"id": "1309373675783184385",

"userId": "1",

"comment": "好了?",

"children": []

}

]

}

]

绝大多数时候我们都会去使用两层型的评论方式做评论

总结

到此这篇关于Java实现评论回复功能的文章就介绍到这了,更多相关Java实现评论回复功能内容请搜索自学编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持自学编程网!

java评论回复功能例子_Java实现评论回复功能的完整步骤相关推荐

  1. java se 导原码_Java SE 8新功能导览:Java开发世界中的重大变化

    java se 导原码 我很自豪,像其他专业团队成员一样,是采用OpenJDK的成员之一,但是从过去8个月就加入了,我们经历了Java SE 8 开发,编译,编码,讨论等各个阶段,直到将其付诸实践为止 ...

  2. java短路运算符有哪些_Java逻辑运算符的短路功能

    逻辑运算包括:与.或.非.异或.共6种运算符.true 表示真.false 表示假. 一.逻辑运算符 下表列出了逻辑运算符: 操作符 描述 &&,& 逻辑与运算符.当且仅当两个 ...

  3. java exec dir的例子_java.lang.Runtime.exec(String[] cmdarray, String[] envp, File dir)方法实例...

    全屏 java.lang.Runtime.exec(String[] cmdarray, String[] envp, File dir)方法执行在指定环境和工作目录的独立进程中指定的命令和参数.字符 ...

  4. java的多态代码例子_java多态例子,java多态代码实例

    下面要给大家分享的是一个多态经典案例,一起来看看这个java多态简单例子吧./*多态的好处:提高了代码的维护性和扩展性: 弊端:父类不能使用子类的特有功能. 要用子类的特有功能,可以: A:创建子类对 ...

  5. java中多态的例子_java中的多态案例

    多态性实际上有两种: 1.方法的多态性: 1.1方法重载:相同的方法名,会根据传入的参数的类型和个数不同执行不同的方法 1.2方法覆写:同一个方法名称,会根据子类的不同实现不同的功能 2.对象的多态性 ...

  6. java中线性结构的例子_java数据结构--线性结构

    一.数据结构 数据结构由数据和结构两部分组成,就是将数据按照一定的结构组合起来,这样不同的组合方式有不同的效率,可根据需求选择不同的结构应用在相应在场景.数据结构大致 分为两类:线性结构(如数组,链表 ...

  7. java读写锁死锁例子_Java并发关于重入锁与读写锁的详解

    这篇文章主要介绍了Java并发编程之重入锁与读写锁,文中相关实例代码详细,测试可用,具有一定参考价值,需要的朋友可以了解下. 重入锁 重入锁,顾名思义,就是支持重进入的锁,它表示该锁能够支持一个线程对 ...

  8. java删除word中批注_Java 添加、回复、删除Word批注

    class="MsoNormal">在word中,批注是一种常用于对特定文档内容进行注解的方法,起到解释说明.标记指正的作用.本篇文章中,将通过Java程序来演示如何来操作批 ...

  9. java中实现工厂日历_Java实现的日历功能完整示例

    本文实例讲述了java实现的日历功能.分享给大家供大家参考,具体如下: 应用名称:Java日历 用到的知识:Java GUI编程,日期操作 开发环境:win8+eclipse+jdk1.8 功能说明: ...

最新文章

  1. Windows和Linux的C/C++ IDE选择
  2. 自定义类模板 重载遇到的问题
  3. ABAP:SmartForms--设计
  4. wap(dopra linux )命令,运营商定制的华为光猫Telnet命令恢复华为界面
  5. Eclipse里git提交冲突rejected – non-fast-forward
  6. cocos2dx Auto-batching的使用
  7. mysql mysqli 修改_php mysqli 增删改查操作
  8. android UI进阶之仿iphone的tab效果
  9. Android反射set/get系统属性(SystemProperties)
  10. 用python处理excel表格_使用Python处理excel表格(openpyxl)及表格中的中文处理
  11. Python str内部功能介绍
  12. Netty权威指南——WebSocket协议开发
  13. mysql汽车网站数据库设计_基于数据库和JAVA的网上汽车租赁管理系统的设计(MySQL)...
  14. Mysql常用技巧总结
  15. html中设置首字母大写,css如何设置英文首字母大写
  16. android ios 微信 备份通讯录备份通讯录备份通讯录,苹果手机怎么备份通讯录?手机通讯录微信联系人备份教程...
  17. 联想T430 WIN8系统换WIN7系统的相关设置
  18. 在bitlocker上锁的情况下,采用win10安装介质安装系统。
  19. 为什么现在很多人在用影刀,影刀突然火起来了?
  20. [spm操作] 什么是ROI,如何做ROI以及批量提取ROI的%signal change的示例程序

热门文章

  1. 实战演练丨SCN太大引发ORA-600[2252]
  2. 记一次 Redis Cluster 宕机引发的事故
  3. 云图说|初识云数据库GaussDB(for Cassandra)
  4. CloudIDE:为开发者写代码开启“加速”模式
  5. KubeEdge@MEC:Kubernetes容器生态与5G的结合
  6. 全面拥抱 FastApi — 多应用程序项目结构规划
  7. 华为数据库2019年度大盘点
  8. 云图说|小云妹带你揭秘数据复制服务DRS四大功能
  9. 机器学习笔记(一)----基本概念
  10. 设计模式的C语言应用-导言-第一章