递归在多级数据结构中的简单应用

哈喽,我是小码,半年多没更新了,这段时间换了新工作,工作也很忙。后续会尽量多写点,坚持确实是一件很难,很酷的事情。最近在公司负责开发商品有关的开发,商品包含类型、款式等属性,而类型可能有一级类型、二级类型甚至是三级类型,针对这种多级分类,这就就不好使用简单的查询了。之前也写了一篇文章,Java递归实现评论多级回复,写的比较简单。本文做一些更加系统、完善的方案。

多级数据结构的场景

多级数据在电商或者后台管理系统中是比较常见,比如博客或者短视频的评论,人员系统的多级部门等等,

评论系统

A 写了一条评论,B 就可以回复 A 评论,C 又可以回复 B.

评论A
├── 评论B,回复A
│   └── 评论C,回复B
└── 评论D,回复A

人员系统

一般人员都是绑定一个企业和部门,企业有分公司,部门会多级部门。每个人员绑定一个部门.

选择部门之后就可以获取对应的人员列表信息。

商品的多级分类

商品的类型,会细分多个类型,有一级分类,二级分类,或者有多级分类,比如黄金,分成黄金精品,黄金精品又分成手镯、项链。手镯又分成固口手镯、开口手镯、卡扣手镯等等。

多级结构解决方案

像这种类似于树形结构的数据,数据一般都会包含idparent_idname等字段,通过idparent_id来关联数据。下面是一个简单的实体:

public class Multistage {public Multistage(Integer id,Integer parentId,String message) {this.id = id;this.parentId = parentId;this.message = message;}/*** id*/private Integer id;/*** 父类id*/private Integer parentId;/*** 名称*/private String name;// 省略get、set}

数据表和上面的实体类似。

1、展示多级接口

展示多级数据接口,就需要使用树的接口。类似下面的接口:

public class ViewMultistage {/*** id*/private Integer id;/*** 父类id*/private Integer parentId;/*** 名称*/private String name;/*** 子集*/private List<ViewMultistage> children = new ArrayList<>();}

上面的几个例子,评论、部门、以及商品的分类,都是需要展示所有数据,所以需要从数据库获取所有数据,再使用代码归类。

针对这种多级、不确定层级数量的,一般都使用递归方法获取。从数据库获取到列表数据,使用递归方式转换:

// 数据库获取数据
List<Multistage> multistageList = "select * from t_xxxx";// 树形结果
ViewMultistage root = new ViewMultistage();// 添加首节点
root.setId(-1);
// 递归添加
add(root,multistageList);
// 结果
List<ViewMultistage> viewMultistageList = root.getChildren();
System.out.println(viewMultistageList);// 递归添加数据
private void add(ViewMultistage rootViewMultistage, List<Multistage> multistageList) {for (Multistage multistage : multistageList) {if (rootViewMultistage.getId().equals(multistage.getParentId())) {ViewMultistage viewMultistage = new ViewMultistage();BeanUtils.copyProperties(multistage, viewMultistage);rootViewMultistage.getChildren().add(viewMultistage);add(viewMultistage, multistageList);}}
}

简略解释一下代码:

  • 获取数据列表,创建树形类。
  • 创建 -1 的虚拟节点,添加到属树形类上。
  • 使用递归不断找到子节点,直到遍历完所有数据。
  • 虚拟节点的子节点 root.getChildren() 就是我们要的结果。

从数据库获取的数据一定要有顺序,子数据不能比父数据排前面。

查询子集数据

如果不是获取所有的数据,只是获取一部分的数据。以部门和人员举例,部门有子部门,子部门有部门人员。要求查询部门以及子部门的人员信息。商品绑定二级款式或者三级款式,但是需要通过一级款式找到对应的下级的商品。

解决问题的重点就是获取到部门以及子部门的集合,这里就有两个方案。

获取所有部门,代码筛选

从数据获取所有的部门数据,遍历列表,筛选出符合条件的数据。比如上面的华南部门,假设 id 为 3,通过如下代码就能获取到部门 id 集合:

Integer id = 3;
Set<Integer> idSet = new HashSet<>();
idSet.add(id);
for (ViewMultistage multistage : viewMultistageList) {Integer parentId = multistage.getParentId();if (idSet.contains(parentId)) {idSet.add(multistage.getId());}
}

通过某个 id 就可以筛选部门以及子部门的集合,然后通过部门 id 的集合就能获取到人员信息。

但是如果只是获取一小部门的子集,却要获取全部数据,有点浪费查询资源。可以在数据库中刷选好数据,通过数据库递归获取数据。

通过数据库递归查找

查询数据大部分时候还是需要查询数据库,通过数据库一步到位,也减少了代码的的书写。将递归的查询方式转移到数据库中,使用到了 Mysql 递归函数 with recursive,用法如下:

WITH RECURSIVE family_tree AS (-- 基础查询:从给定的一级 id 开始SELECTid,parent_idFROM parentsWHERE id = 1  -- 替换为你要查询的一级 idUNION ALL-- 递归查询:查找子节点SELECTp.id,p.parent_idFROMparents pINNER JOIN family_tree ft ON p.parent_id = ft.id)select tu.* from family_tree ft
left join t_user tu on tu.dept_id = ft.id

分析with recursive用法:

  • WITH RECURSIVE family_tree AS 是一个固定用法,将 () 查询的数据结果返回给 family_tree。
  • 函数体里面包含两部分,起始值循环值
    • 起始值:确认首节点的位置,上面例子以 id = 1作为起始值。
    • 循环值:以 id = 1 找到 parent_id 为 1 的数据,假设这个 id 为 2,然后找到 parent_id 的数据,一直循环查找,直到查询结束。
    • 上面的 family_tree 就类似通过父部门获取到所有的子部门,使用用户表关联,就能获取所有部门以及子部门的用户信息。

总结

多级数据结构在项目开发中是一种比较常见的数据结构,比如:

  • 评论,评论回复评论,其他评论再回复评论。
  • 企业部门,部门有子部门,或者公司有子公司。
  • 商品分类有一级分类,二级分类。

多级数据结构需要解决两个问题,一个是查询所有数据,另外一个是查询部分数据,这两个都需要使用到递归的查询。

  • 查询所有数据
    • 比较少的数据,就可以查询所有的数据,从数据库查询到所以数据,按照添加时间的先后排序,再使用递归的方式将数据组装成一个树形结构。
    • 如果是评论的数据,就需要存储评论的等级,先分页获取一级的评论,再通过一级评论获取下级评论。
  • 查询部分数据
    • 通过某个一级部门获取所有的子部门,有两种方式,第一种是获取所有的部门数据,再循环遍历数据,将符合的数据放到一个集合中。
    • 第二种是使用 Mysql 递归,使用with recursive 先确定一个起始值,在不断的遍历下级部门。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/23370.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

视频推广短信:新时代的营销利器(视频短信XML接口示例)

随着移动互联网的普及&#xff0c;短信已经不再是简单的文字信息传递工具&#xff0c;而是逐渐演变为一种有效的推广手段。特别是当视频与短信结合时&#xff0c;它所带来的营销效率更是令人瞩目。 一、视频推广短信的特点 1.直观性&#xff1a;与传统的文字短信相比&#xf…

游戏盾之应用加速,何为应用加速

在数字化时代&#xff0c;用户对于应用程序的防护要求以及速度和性能要求越来越高。为了满足用户的期望并提高业务效率&#xff0c;应用加速成为了不可忽视的关键。 应用加速是新一代的智能分布式云接入系统&#xff0c;采用创新级SD-WAN跨域技术&#xff0c;针对高防机房痛点进…

令人瞠目结舌的8个ChatGPT-4o提示词

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

【python】OpenCV—Bitplane

学习来自&#xff1a; 位平面分割&#xff08;Bit-Plane Slicing&#xff09;使用OpenCVPython进行图像处理的初学者指南 位平面 位平面&#xff08;bitplane&#xff09;是一个在计算机科学中用于描述图像数据的概念&#xff0c;具体定义如下&#xff1a; 【定义】&#x…

《手把手教你》系列练习篇之10-python+ selenium自动化测试(详细教程)

1. 简介 今天我们继续前边的练习&#xff0c;学习和练习一下&#xff1a;如何使用webdriver方法获取当前测试页面的URL、如何获取当前页面的title、如何打开浏览器的一个新建页面、如何操作单选按钮等等&#xff0c;这些小练习&#xff0c;来巩固基础。 2. webdriver方法获取…

​谁用谁知道,教师实用工具分享​

老师们面临着日益增长的教学和管理任务。为了有效提升工作效率&#xff0c;一些实用的工具成为了老师们不可或缺的助手。给大家分享几款教师必备的工具&#xff0c;帮助教师们在教学和管理工作中更加得心应手。 1. 知乎&#xff1a;知识的海洋 知乎是一个中文问答社区&#xf…

Docker-compose安装、使用,容器化部署springboot项目

一、docker-compose的安装 1、按官网的方式去安装 1&#xff09;下载docker-compose curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose 若…

【微机原理及接口技术】中断系统

【微机原理及接口技术】中断系统 文章目录 【微机原理及接口技术】中断系统前言一、中断概述中断的基本概念中断处理过程 二、8086/8088中断系统中断类型中断响应过程中断向量表内部中断服务程序 总结 前言 本篇文章我们会讲到中断的概述&#xff0c;8086/8088中断系统。 一、…

bootstrap5-学习笔记3-文字格式+表格+徽章

参考&#xff1a; Bootstrap5 教程 | 菜鸟教程 https://www.runoob.com/bootstrap5/bootstrap5-tutorial.html Bootstrap 入门 Bootstrap v5 中文文档 v5.3 | Bootstrap 中文网 https://v5.bootcss.com/docs/getting-started/introduction/ 之前用bootstrap2和3比较多&#x…

微软云计算Windows Azure(三)

目录 五、Windows Azure Marketplace六、Windows Azure服务平台&#xff08;一&#xff09;网站&#xff08;二&#xff09;虚拟机&#xff08;三&#xff09;云服务&#xff08;四&#xff09;移动服务&#xff08;五&#xff09;大数据处理&#xff08;六&#xff09;媒体支持…

点赋科技:在招聘会上绽放光彩,助力青春梦想起航

在近日举行的青年企业家协会招聘会暨长江大学就业实习双选会上&#xff0c;点赋科技以其独特的魅力和强大的实力吸引了众多求职者的关注。 点赋科技的展位前人头攒动&#xff0c;公司的招聘团队热情地与每一位求职者交流。他们详细介绍了公司的发展历程、业务范围、企业文化以及…

LeetCode-704. 二分查找【数组 二分查找】

LeetCode-704. 二分查找【数组 二分查找】 题目描述&#xff1a;解题思路一&#xff1a;注意开区间和闭区间背诵版&#xff1a;解题思路三&#xff1a; 题目描述&#xff1a; 给定一个 n 个元素有序的&#xff08;升序&#xff09;整型数组 nums 和一个目标值 target &#xf…

杨校老师项目之基于52单片机的霍尔自行车码表【嵌入式】

获取全套资料&#xff1a; 有偿获取&#xff1a;mryang511688 技术&#xff1a;C语言、单片机等 摘要&#xff1a; 本项目基于单片机设计了一款霍尔自行车码表。该系统实现了骑行过程中即时显示行驶速度、行径里程、显示当前时刻以及超速危险报警等功能。有助于骑行者在骑行过…

“解锁财富新密码:订单共享商业模式的革命性力量“

在当前的商业环境中&#xff0c;创新和效率是企业生存和发展的关键。今天&#xff0c;我们向您介绍一种革命性的商业模式——订单共享商业模式&#xff0c;它正在改变企业家们对新零售的理解和实践。 订单共享商业模式&#xff0c;是一种通过整合和优化不同商家的订单资源&…

从零开始:如何用Electron将chatgpt-plus.top 打包成EXE文件

文章目录 从零开始&#xff1a;如何用Electron将chatgpt-plus.top 打包成EXE文件准备工作&#xff1a;Node.js和npm国内镜像加速下载初始化你的Electron项目创建你的Electron应用运行你的Electron应用为你的应用设置图标打包成EXE文件结语 从零开始&#xff1a;如何用Electron将…

【动手学深度学习】使用块的网络(VGG)的研究详情

目录 &#x1f30a;1. 研究目的 &#x1f30a;2. 研究准备 &#x1f30a;3. 研究内容 &#x1f30d;3.1 多层感知机模型选择、欠拟合和过拟合 &#x1f30d;3.2 练习 &#x1f30a;4. 研究体会 &#x1f30a;1. 研究目的 理解块的网络结构&#xff1b;比较块的网络与传统…

Qt如何让按钮的菜单出现在按钮的右侧

直接上代码&#xff0c;我们用到了一个eventfilter的函数功能。这个函数比较厉害和重要&#xff0c;大家务必经常拿出来看看。 void MainWindow::initMenu() { QMenu* menuLiXiang new QMenu; QAction* actXiangMuZhangCheng new QAction("项目章程"); …

【Cesium4UE】使用问题及解法统计

本期作者&#xff1a;尼克 易知微3D引擎技术负责人 1.加载3dtiles模型很慢 1.3dtiles是否做了重建顶层处理。如果3dtiles的tiles块太多使用CesiumLab重建顶层。 2.将3dtiles模型放置到固态硬盘中 3.如果有多块3dtiles&#xff0c;考虑使用CesiumLab合并3dtiles处理 4.如果不需…

OSG天空图代码

osgEarth // 创建天空选项osgEarth::Util::SkyOptions skyOptions;// 设置天空的坐标系统&#xff08;可选&#xff09;skyOptions.coordinateSystem() osgEarth::Util::SkyOptions::COORDSYS_ECEF;// 设置一天中的小时数&#xff08;可选&#xff09;skyOptions.hours() 12.…

基于springboot实现社区养老服务系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现社区养老服务系统演示 摘要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本社区养老服务系统就是在这样的大环境下诞生&#xff0c;其可以帮助…