当前位置: 首页 > news >正文

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}]}]}
]
http://www.lryc.cn/news/520552.html

相关文章:

  • FreeCAD集成gmsh源码分析
  • K8s 集群 IP 地址管理指南(K8s Cluster IP Address Management Guide)
  • Debye-Einstein-模型拟合比热容Python脚本
  • OpenCV的图像分割
  • 【源码+文档+调试讲解】农产品研究报告管理系统
  • 【STM32-学习笔记-7-】USART串口通信
  • 高可用虚拟IP-keepalived
  • AI多模态技术介绍:视觉语言模型(VLMs)指南
  • 高效工作流:用Mermaid绘制你的专属流程图;如何在Vue3中导入mermaid绘制流程图
  • uniApp通过xgplayer(西瓜播放器)接入视频实时监控
  • ws 配置 IngressRoute 和 http一样
  • IMX6ULL的IOMUXC寄存器和SNVS复用寄存器似乎都是对引脚指定复用功能的,那二者有何区别?
  • LabVIEW实现动态水球图的方法
  • 【江协STM32】11-2/3 W25Q64简介、软件SPI读写W25Q64
  • 《自动驾驶与机器人中的SLAM技术》ch2:基础数学知识
  • 算法日记2:洛谷p3853路标设置(二分答案)
  • 浅谈云计算06 | 云管理系统架构
  • Blender常规设置
  • c++ 中的容器 vector、deque 和 list 的区别
  • 【物流管理系统 - IDEAJavaSwingMySQL】基于Java实现的物流管理系统导入IDEA教程
  • 数据集-目标检测系列- 电话 测数据集 call_phone >> DataBall
  • VUE3 自定义指令的介绍
  • HTML学习笔记记录---速预CSS(2) 复合属性、盒子模型、边框线、浮动、定位
  • 二 RK3568 固件中打开 ADB 调试
  • centos9设置静态ip
  • 【Python】Python之Selenium基础教程+实战demo:提升你的测试+测试数据构造的效率!
  • 内网服务器添加共享文件夹功能并设置端口映射
  • 第三十六章 Spring之假如让你来写MVC——拦截器篇
  • TypeScript语言的学习路线
  • Python爬虫-汽车之家各车系周销量榜数据