MYSQL 查询树形结构数据,查询某个节点下的所有子节点数据。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MYSQL 查询树形结构数据,查询某个节点下的所有子节点数据。相关的知识,希望对你有一定的参考价值。

列如 有个 A表
当前节点 节点名称 上级节点名称

字段有 : id name super

1 一级

2 二级 1

3 三级 2

4 四级 3

不固定可能还有更多层。
请各位大神写个列子,谢谢大家了!

参考技术A java版的实际例子。类同你说的情况

private void findChildList(AssetType parent,List<AssetType> list)
String hql = "from AssetType a where a.parentAssetType.assetTypeId=? ORDER BY a.sort,a.assetTypeName asc";

List<AssetType> childList = this.assetTypeDao
.getEntityManager()
.createQuery(hql)
.setParameter(1, parent.getAssetTypeId())
.getResultList();
int size = childList.size();
if(size>0)
for (int i = 0; i < size; i++)
AssetType assetType = childList.get(i);
List<AssetType> childs = assetType.getChildAssetType();
if(childs.size()>0)
list.addAll(childs);
this.findChildList(assetType, list);//递归查询节点的子节点



本回答被提问者采纳

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 查询树形结构数据,查询某个节点下的所有子节点数据。的主要内容,如果未能解决你的问题,请参考以下文章

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

mysql树形结构的查询案例

MySQL疑难杂症如何将树形结构存储在数据库中(方案三 Closure Table)

MySQL实现递归查找树形结构

MySQL递归查询所有子节点,树形结构查询

MySQL疑难杂症如何将树形结构存储在数据库中(方案二 Path Enumeration)