上一篇文章介绍了通过mybatisplus查询树形结构的方式
本文介绍通过递归方法查询树形结构
步骤是先查询所有数据,然后通过递归重新构建树形结构。对比mybatisplus查询,减少过多次数据库IO,把构建查询的任务放到内存中,虽然时间和空间复杂度较高,但是少量数据的情况下,效率更快
表结构
| id | name | code | parentId | is_del |
|---|---|---|---|---|
| 1 | A集团 | 1 | 0 | 0 |
| 2 | B公司 | 2 | 1 | 0 |
| 3 | C部门 | 3 | 2 | 0 |
如果创建树形结构,在数据表中必须存在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;
}
```