java 查询树结构数据,无限层级树结构通用方法
1、数据库表数据

2、controller层TestTree简单测试
@RestController
@RequestMapping("/test")
public class testTreeController {@Autowiredprivate TestTreeService testTreeService;@GetMapping("/list")public List<TestTree> List(TestTree tree){List<TestTree> testTrees = testTreeService.getTreeList(tree);return testTrees;}
}
3、TestTree实体类
@TableName(value ="test_tree")
@Data
public class TestTree implements TreeNode {/*** id*/@TableIdprivate String id;/*** 父级id*/private String pid;/*** 名称*/private String name;/*** 类型*/private String type;@TableField(exist = false)private static final long serialVersionUID = 1L;@TableField(exist = false)private List childNodeList = new ArrayList<>();@Overridepublic void setChildNodeList(List childNodeList) {this.childNodeList = childNodeList;}@Overridepublic List getChildNodeList() {return childNodeList;}
}
4、TestTreeService 接口
public interface TestTreeService extends IService<TestTree> {/*** 查找树结构List* @param tree 查询条件* @return 树结构结果*/List<TestTree> getTreeList(TestTree tree);
}
5、TestTreeServiceImpl 实现类
@Service
public class TestTreeServiceImpl extends ServiceImpl<TestTreeMapper, TestTree>implements TestTreeService{public List<TestTree> selectList(TestTree tree) {LambdaQueryWrapper<TestTree> queryWrapper = new LambdaQueryWrapper();queryWrapper.eq(ObjectUtil.isNotEmpty(tree.getId()), TestTree::getId, tree.getId());queryWrapper.like(ObjectUtil.isNotEmpty(tree.getName()), TestTree::getName, tree.getName());queryWrapper.like(ObjectUtil.isNotEmpty(tree.getType()), TestTree::getType, tree.getType());return super.list(queryWrapper);}@Overridepublic List<TestTree> getTreeList(TestTree tree) {//查询数据List<TestTree> list = this.selectList(tree);//封装树结构,通用方法,参数为传入的ListList<TestTree> treeList = TreeList.getTreeList(list);//返回树结构Listreturn treeList;}
}
6、构建树结构
6.1、定义TreeNode
public interface TreeNode<E extends TreeNode> {/*** 获取节点ID*/String getId();/*** 获取父ID*/String getPid();void setChildNodeList(List<E> childNodeList);/*** 子节点数据*/List<E> getChildNodeList();
}
6.2、构建树结构
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;/*** 处理树形结构的数据*/
public final class TreeList {public static <E extends TreeNode> List<E> getTreeList(List<E> allData){//通过流操作,过滤出所有pid为空或者为null的节点,就是树的顶层节点List<E> topNode = allData.stream().filter(item -> Objects.isNull(item) || StrUtil.isBlank(item.getPid())).collect(Collectors.toList());//移除所有pid为空或为null的节点allData.removeIf(item->Objects.isNull(item) || StrUtil.isBlank(item.getPid()));//将剩余节点按pid分租,结果存储在map中,pid作为键,节点列表作为值Map<String, List<E>> map = allData.stream().collect(Collectors.groupingBy(TreeNode::getPid));//构建树形结构buildTree(topNode,map);//返回顶层节点列表return topNode;}//构建树形结构public static <E extends TreeNode> void buildTree(List<E> topNode, Map<String,List<E>> map){for (E node : topNode) {//遍历顶层节点,如果节点为null,则跳过if (Objects.isNull(node)){continue;}//获取当前节点的idString id = node.getId();//从map中获取其子节点列表List<E> treeNodes = map.get(id);//将其设置为当前节点的子节点列表node.setChildNodeList(treeNodes);//如果当前节点没有子节点,则继续下一个节点if (CollectionUtil.isEmpty(treeNodes)){continue;}//对当前节点的子节点列表递归调用buildTree方法,继续构建树形结构buildTree(treeNodes,map);}}
}
7、postman测试
结果
[{"id": "1","pid": null,"name": "第一层级","type": "1","childNodeList": [{"id": "2","pid": "1","name": "第二层级","type": "2","childNodeList": [{"id": "3","pid": "2","name": "第三层级","type": "3","childNodeList": [{"id": "4","pid": "3","name": "第四层级","type": "4","childNodeList": [{"id": "5","pid": "4","name": "第五层级","type": "5","childNodeList": null}]}]},{"id": "6","pid": "2","name": "次二层级","type": "6","childNodeList": null}]}]}
]相关文章:
java 查询树结构数据,无限层级树结构通用方法
1、数据库表数据 2、controller层TestTree简单测试 RestController RequestMapping("/test") public class testTreeController {Autowiredprivate TestTreeService testTreeService;GetMapping("/list")public List<TestTree> List(TestTree tree)…...
FreeCAD集成gmsh源码分析
目录 gmsh模块界面获取gmsh的版本执行gmsh网格划分gmsh模块界面 这个界面是用PySide来写的,PySide是QT的python绑定,具体代码在task_mesh_gmsh.py文件中。目前这个界面非常的简陋,没有对接gmsh稍微高级一点的功能。界面对应的事件处理是在gmshtools.py中。这里只分析“Gmsh …...
K8s 集群 IP 地址管理指南(K8s Cluster IP Address Management Guide)
K8s 集群 IP 地址管理指南 概述 你是否在小型初创公司或大型企业工作,并正在为公司评估 Kubernetes?你可能正在考虑运行十几个或更多的 Kubernetes (K8s) 集群。你期望每个集群支持几百个 K8s 节点,每个节点可能有 50 到 100 个 K8s Pod。这…...
Debye-Einstein-模型拟合比热容Python脚本
固体比热模型中的德拜模型和爱因斯坦模型是固体物理学中用于估算固体热容的两种重要原子振动模型。 爱因斯坦模型基于三种假设:1.晶格中的每一个原子都是三维量子谐振子;2.原子不互相作用;3.所有的原子都以相同的频率振动(与德拜…...
OpenCV的图像分割
1、基本概念 图像分割是计算机视觉和图像处理中的一个关键步骤,它指的是将图像划分为多个区域或对象的过程。这些区域或对象在某种特性(如颜色、形状、纹理或亮度等)上是一致的或相似的,而在不同区域之间则存在明显的差异。图像分…...
【源码+文档+调试讲解】农产品研究报告管理系统
摘 要 农产品研究报告管理系统是一个旨在收集、整理、存储和分析农产品相关研究数据的综合性平台。农产品研究报告管理系统通常包含一个强大的数据库,它能够处理大量的研究数据,并对这些数据进行有效的管理和备份。农产品研究报告管理系统是现代农业科学…...
【STM32-学习笔记-7-】USART串口通信
文章目录 USART串口通信Ⅰ、硬件电路Ⅱ、常见的电平标准Ⅲ、串口参数及时序Ⅳ、STM32的USART简介数据帧起始位侦测数据采样波特率发生器 Ⅴ、USART函数介绍Ⅵ、USART_InitTypeDef结构体参数1、USART_BaudRate2、USART_WordLength3、USART_StopBits4、USART_Parity5、USART_Mode…...
高可用虚拟IP-keepalived
个人觉得华为云这个文档十分详细:使用虚拟IP和Keepalived搭建高可用Web集群_弹性云服务器 ECS_华为云 应用场景:虚拟IP技术。虚拟IP,就是一个未分配给真实主机的IP,也就是说对外提供数据库服务器的主机除了有一个真实IP外还有一个…...
AI多模态技术介绍:视觉语言模型(VLMs)指南
本文作者:AIGCmagic社区 刘一手 AI多模态全栈学习路线 在本文中,我们将探讨用于开发视觉语言模型(Vision Language Models,以下简称VLMs)的架构、评估策略和主流数据集,以及该领域的关键挑战和未来趋势。通…...
高效工作流:用Mermaid绘制你的专属流程图;如何在Vue3中导入mermaid绘制流程图
目录 高效工作流:用Mermaid绘制你的专属流程图 一、流程图的使用场景 1.1、流程图flowChart 1.2、使用场景 二、如何使用mermaid画出优雅的流程图 2.1、流程图添加图名 2.2、定义图类型与方向 2.3、节点形状定义 2.3.1、规定语法 2.3.2、不同节点案例 2.…...
uniApp通过xgplayer(西瓜播放器)接入视频实时监控
🚀 个人简介:某大型国企资深软件开发工程师,信息系统项目管理师、CSDN优质创作者、阿里云专家博主,华为云云享专家,分享前端后端相关技术与工作常见问题~ 💟 作 者:码喽的自我修养ǹ…...
ws 配置 IngressRoute 和 http一样
ws 配置 IngressRoute 和 http一样 apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata:name: web-ws-ingressroutenamespace: starp spec:entryPoints:- webroutes:- match: Host(webws.we…...
IMX6ULL的IOMUXC寄存器和SNVS复用寄存器似乎都是对引脚指定复用功能的,那二者有何区别?
IMX6ULL 的 IOMUXC 和 SNVS(Secure Non-Volatile Storage)复用寄存器都是用于配置引脚功能的,但它们的作用范围、目的和使用场景存在明显区别。以下是它们的差异分析: 1. IOMUXC(I/O Multiplexer Control)寄…...
LabVIEW实现动态水球图的方法
水球图是一种直观展示百分比数据的图表,常用于数据监测与展示。LabVIEW 虽不直接支持水球图绘制,但可通过图片控件动态绘制波形,或借助 HTMLCSS 的 Web 控件实现。此外,还可以结合 Python 等第三方工具生成水球图,LabV…...
【江协STM32】11-2/3 W25Q64简介、软件SPI读写W25Q64
1. W25Q64简介 W25Qxx系列是一种低成本、小型化、使用简单的非易失性存储器,常应用于数据存储、字库存储、固件程序存储等场景存储介质:Nor Flash(闪存)时钟频率:80MHz / 160MHz (Dual SPI) / 320MHz (Quad SPI)存储容…...
《自动驾驶与机器人中的SLAM技术》ch2:基础数学知识
目录 2.1 几何学 向量的内积和外积 旋转矩阵 旋转向量 四元数 李群和李代数 SO(3)上的 BCH 线性近似式 2.2 运动学 李群视角下的运动学 SO(3) t 上的运动学 线速度和加速度 扰动模型和雅可比矩阵 典型算例:对向量进行旋转 典型算例:旋转的复合 2.3 …...
算法日记2:洛谷p3853路标设置(二分答案)
一、题目: 二、解题思路: 2.1:首先,我们二分空旷指数 1、因为题目中要求我们求解最大值最小应该是属于第二类模型2.也就是说,当check()函数为true时候,说明这个空旷指数是成立的,对应的路标数…...
浅谈云计算06 | 云管理系统架构
云管理系统架构 一、云管理系统架构(一)远程管理系统(二)资源管理系统(三)SLA 管理系统(四)计费管理系统 二、安全与可靠性保障(一)数据安全防线(…...
Blender常规设置
移动:Shift鼠标中键 旋转:鼠标中键 缩放:Ctrl鼠标中键...
c++ 中的容器 vector、deque 和 list 的区别
表格汇总: 容器存储结构随机访问性能中间插入/删除性能两端插入/删除性能内存管理特点迭代器类型适用场景vector连续存储的动态数组 O ( 1 ) O(1) O(1) O ( n ) O(n) O(n)(需要移动元素)末尾: O ( 1 ) O(1) O(1),头部…...
地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...
Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...
c++第七天 继承与派生2
这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分:派生类构造函数与析构函数 当创建一个派生类对象时,基类成员是如何初始化的? 1.当派生类对象创建的时候,基类成员的初始化顺序 …...
django blank 与 null的区别
1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是,要注意以下几点: Django的表单验证与null无关:null参数控制的是数据库层面字段是否可以为NULL,而blank参数控制的是Django表单验证时字…...
一些实用的chrome扩展0x01
简介 浏览器扩展程序有助于自动化任务、查找隐藏的漏洞、隐藏自身痕迹。以下列出了一些必备扩展程序,无论是测试应用程序、搜寻漏洞还是收集情报,它们都能提升工作流程。 FoxyProxy 代理管理工具,此扩展简化了使用代理(如 Burp…...
yaml读取写入常见错误 (‘cannot represent an object‘, 117)
错误一:yaml.representer.RepresenterError: (‘cannot represent an object’, 117) 出现这个问题一直没找到原因,后面把yaml.safe_dump直接替换成yaml.dump,确实能保存,但出现乱码: 放弃yaml.dump,又切…...
Java并发编程实战 Day 11:并发设计模式
【Java并发编程实战 Day 11】并发设计模式 开篇 这是"Java并发编程实战"系列的第11天,今天我们聚焦于并发设计模式。并发设计模式是解决多线程环境下常见问题的经典解决方案,它们不仅提供了优雅的设计思路,还能显著提升系统的性能…...
