MySQL查询父节点下面的所有子孙节点,查询用户列表时多级(公司)部门处理,根据反射,递归树形结构工具类
Posted 符华-
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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()));
}
效果:
以上是关于MySQL查询父节点下面的所有子孙节点,查询用户列表时多级(公司)部门处理,根据反射,递归树形结构工具类的主要内容,如果未能解决你的问题,请参考以下文章