概述
在项目中,我们经常涉及单张表数据进行树形目录结构展示(即具有层级关系的数据结构),比如菜单层级展示、商品分类展示等。
思路
单张表之间要具备层级关系,必然会有能体现父子之间的字段,比如常见的id和parentId比如这样一张表pid为0时即为最高层级,pid为 1366的是id为1366的孩子,在上面的体现是
裤子和上衣都在衣服这一个分类下面要实现这张表树形结构的展示,我们一方面得在该表对应的实体类里添加一个自身的集合childList作为其孩子的集合。
具体实现
这里我是将它封装成一个工具类使用。
注意:这里默认表里的父级字段为 parentId
/**
* <p>
* 构建树的时候需要实体继承此类
* </p>
*
* @author 吴焕业
* @Modified By:
* @since 2020/10/15 17:42
*/
@Data
public class TreeNode<C extends TreeNode<?>>{
/**
* 父id
*/
private String parentId;
/**
* 子节点j集合
* 非数据库字段
*/
@TableField(exist = false)
private List<TreeNode> children;
}
工具类实现树形结构的展示(递归思想找子节点)
/**
* @description: 生成树工具(根节点可有多个)
* @author 吴焕业
* @param treeNodes 所有节点(所有数据)
* @param parentId 指定根节点的唯一标识
* @since 2020/10/15 18:01
* @Modified By:
* @return
*/
public static <T extends TreeNode>List<T> build(List<T> treeNodes, String parentId){
if (parentId == null){
return null;
}
List<T> rootNodes = new ArrayList<>();
for (T t : treeNodes){
if (parentId.equals(t.getParentId())){
//得到根节点
rootNodes.add(t);
}
}
for (T t : rootNodes){
t.setChildren(getChildNodes(t,treeNodes));
}
return rootNodes;
}
/**
* @description: 获得子节点
* @author 吴焕业
* @param t
* @param treeNodes
* @since 2020/10/6 18:27
* @Modified By:
* @return
*/
private static <T extends TreeNode>List<TreeNode> getChildNodes(TreeNode t,List<T> treeNodes){
List<TreeNode> childNodes = new ArrayList<>();
for (TreeNode t1 : treeNodes){
if (t1.getParentId().equals(t.getId())){
childNodes.add(t1);
}
}
if (childNodes.size() == 0){
return null;
}
for (TreeNode t1 : childNodes){
t1.setChildren(getChildNodes(t1,treeNodes));
}
return childNodes;
}
总结
要实现树形结构的步骤:
- 表设计要有父子级关系(一般用 id 和 parentId)
- 实体要新增 子节点 的集合变量,一般用List接收
- 查找获得所有符合要求的数据,通过遍历得到 父节点集合,遍历父节点集合,遍历子节点结合,父节点的id和子节点的父id相等时,说明该节点数属于当前父节点的孩子,将其放入父节点的孩子集合中,遍历结束后,将子节点集合赋值给 集合变量。(这里用递归思想实现)