MySQL查询父节点下面的所有子孙节点,查询用户列表时多级(公司)部门处理,根据反射,递归树形结构工具类

MySQL查询父节点下面的所有子孙节点

在这里插入图片描述

-- 获取某个菜单的所有子孙节点同理

SELECT id,dept_name,parent_id
FROM
		(SELECT id,parent_id,dept_name FROM sys_dept where parent_id > 0 ORDER BY parent_id, sort) a,
		(SELECT @pv :=1) b
WHERE (FIND_IN_SET(parent_id,@pv)>0 And @pv := concat(@pv, ',', id))

执行结果:
在这里插入图片描述

查询用户列表时多级(公司)部门处理

SELECT a.id,a.user_name,a.real_name,a.phone_number,a.dept_id,a.status,b.parent_id,b.dept_name, 
		if(c.parent_id = 0,null,c.dept_name) parentName,
		if(c.parent_id = 0,c.dept_name,(SELECT dept_name FROM sys_dept d WHERE c.parent_id=d.id))  comName
FROM sys_user a
LEFT JOIN sys_dept b on a.dept_id=b.id
LEFT JOIN sys_dept c on b.parent_id=c.id

执行结果:
在这里插入图片描述

根据反射,递归树形结构工具类

import cn.hutool.core.util.ReflectUtil;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;


/**
 * 构建树结构工具类
 * @author Admin
 */
public class TreeUtil {
    
    

	/**
     * 获取前端所需树结构
     */
    public static<T> List<T> buildTree(List<T> list) {
    
    
        //获取根节点
        List<T> root = buildTree(list, 0L);
        getChild(root, list);
        return root;
    }
    
    private static<T> List<T> buildTree(List<T> dataList,Long pid){
    
    
        List<T> list= new ArrayList<>();
        Iterator<T> it = dataList.iterator();
        while (it.hasNext()) {
    
    
            T t = it.next();
            Long parentId = (Long)getFieldValue(t,"parentId");
            if (parentId.intValue()==pid.intValue()) {
    
    
                list.add(t);
                it.remove();
            }
        }
        return list;
    }
    
    /**
     * 递归子节点
     */
    private static<T> void getChild(List<T> root,List<T> list){
    
    
        try {
    
    
            for (T nav : root) {
    
    
                Long id = (Long)getFieldValue(nav,"id");
                List<T> childList = buildTree(list, id);
				getChild(childList, list);
				//这里要注意,获取实体类的children属性时,要将 children 设置成public,如果时private会报错。
                Field child = ReflectUtil.getField(nav.getClass(), "children");
                child.set(nav,childList);
            }
        }catch (Exception e){
    
    
            e.printStackTrace();
        }
    }

    private static<T> Object getFieldValue(T t,String fieldName){
    
    
        Field field = ReflectUtil.getField(t.getClass(), fieldName);
        return ReflectUtil.getFieldValue(t, field);
    }

}

使用:

@Data
public class SysMenu {
    
    

    @ApiModelProperty(value = "id")
    @TableId(type = IdType.AUTO)
    private Long id;

    @ApiModelProperty(value = "父菜单ID")
    @TableField("parent_id")
    private Long parentId;

    @ApiModelProperty(value = "菜单名称")
    @TableField("name")
    private String name;
	
	//...
    //省略其他属性
    //...

	//这里要将 children 设置成public,否则在 TreeUtil 通过反射获取字段时无法获取,会报错
    @ApiModelProperty(value = "子菜单")
    public transient List<SysMenu> children = new ArrayList<>();

}
/**
 * TreeVo树结构实体类
 * @author Admin
 */
@Data
public class TreeVo implements Serializable {
    
    
    private static final long serialVersionUID = 1L;

    /** 节点ID */
    private Long id;

    /** 节点名称 */
    private String label;

    /** 父级id */
    private Long parentId;

    /** 子节点 */
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    private List<TreeVo> children;

    public TreeVo() {
    
     }

    public TreeVo(SysDept dept) {
    
    
        this.id = dept.getId();
        this.label = dept.getName();
        this.parentId = dept.getParentId();
        this.children = dept.getChildren().stream().map(TreeVo::new).collect(Collectors.toList());
    }

    public TreeVo(SysMenu menu) {
    
    
        this.id = menu.getId();
        this.label = menu.getName();
        this.parentId = menu.getParentId();
        this.children = menu.getChildren().stream().map(TreeVo::new).collect(Collectors.toList());
    }

}
@GetMapping("/treeMenuList")
public ResultVo treeMenuList() {
    
    
    List<SysMenu> list= sysMenuService.list();
    List<SysMenu> trees = TreeUtil.buildTree(list);
    return ResultUtil.success(trees.stream().map(TreeVo::new).collect(Collectors.toList()));
}

效果:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43165220/article/details/119568340