递归查询树形结构--递归查询

233 阅读2分钟

上一篇文章介绍了通过mybatisplus查询树形结构的方式

本文介绍通过递归方法查询树形结构

步骤是先查询所有数据,然后通过递归重新构建树形结构。对比mybatisplus查询,减少过多次数据库IO,把构建查询的任务放到内存中,虽然时间和空间复杂度较高,但是少量数据的情况下,效率更快

表结构

idnamecodeparentIdis_del
1A集团100
2B公司210
3C部门320

如果创建树形结构,在数据表中必须存在parentid,记录的就是父节点的ID

实体类

//关联数据表
@TableName("dept")
public class DeptTree implements Serializable {

    private static final long serialVersionUID = 1L;
    //设置关联主键ID,并且设置自增
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    @ApiModelProperty("名称")
    private String name;

    @ApiModelProperty("父部门id")
    private Long parentId;

    @ApiModelProperty("编码")
    private String code;

    @ApiModelProperty("是否删除")
    private Integer isDel;
    
    /**
     * 子节点
     */
    @ApiModelProperty("子集")
    @TableField(exist = false)
    private List<Dept> children = new ArrayList<>();
}

构建过程

首先获取条件内的list,因为对应业务条件不同,这里不做展示

然后从上级到下级开始递归查询是否存在子节点,子节点是否有子节点

将构建好的数据放到children

    public List<Dept> buildDeptTree(List<Dept> depts) {
        List<Dept> returnList = new ArrayList<Dept>();
        List<Long> tempList = depts.stream().map(Dept::getId).collect(Collectors.toList());
        for (Dept dept : depts) {
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(dept.getParentId())) {
                recursionFn(depts, dept);
                returnList.add(dept);
            }
        }
        if (returnList.isEmpty()) {
            returnList = depts;
        }
        return returnList;
    }

    /**
     * 递归列表
     *
     * @param list 列表
     * @param t    t
     * @author messi
     * @date 2024/11/06
     */
    private void recursionFn(List<Dept> list, Dept t) {
        // 得到子节点列表
        List<Dept> childList = getChildList(list, t);
        t.setChildren(childList);
        for (Dept tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild);
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<Dept> getChildList(List<Dept> list, Dept t) {
        List<Dept> tlist = new ArrayList<Dept>();
        Iterator<Dept> it = list.iterator();
        while (it.hasNext()) {
            Dept n = (Dept) it.next();
            if (StringUtils.isNotBlank(String.valueOf(n.getParentId()))
                    && n.getParentId().longValue() == t.getId().longValue()) {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<Dept> list, Dept t) {
        return getChildList(list, t).size() > 0 ? true : false;
    }
    ```