首页 > 数据库 >MySql存储树形结构,Java实现根据节点找到父节点,根据节点找到子节点

MySql存储树形结构,Java实现根据节点找到父节点,根据节点找到子节点

时间:2023-11-22 15:55:59浏览次数:34  
标签:Java String cId List trees id MySql 节点

目录

数据表设计

id parent_id name level
1 0 食物 1
2 1 蔬菜 2
3 1 水果 2
4 2 茄果类 3
5 2 叶菜类 3
6 3 浆果类 3
7 3 瓜果类 3
8 4 番茄 4
9 4 辣椒 4
10 5 生菜 4
11 6 桑葚 4

image

id:自增
parent_id:其父结点的id(如图,食物为根结点,所以没有parent_id,或为0)
level:树的深度

生成树(递归方式)

    @Override
    public List<CorpusTagsDTO> selectTagTree(String id) {
        //在数据库中查询所有数据
        List<Tags> trees = tagsMapper.selectList(new QueryWrapper<Tags>());
        // 根节点默认为0,即第一层权限的pid为0
        return getChildren(trees, id);
    }

    /**
     * 递归查询pId的所有子树
     *
     * @param trees  全树列表
     * @param pId 当前id
     * @return 子树列表
     */
    private List<CorpusTagsDTO> getChildren(List<Tags> trees, String pId) {
        // 筛选出pId权限的子权限
        List<Tags> childPrivs = trees.stream()
                .filter(i -> i.getParentId().equals(pId)).collect(Collectors.toList());
        // 转vo
        List<CorpusTagsDTO> children = childPrivs.stream()
                .map(i -> {
                    CorpusTagsDTO corpusTagsDTO = new CorpusTagsDTO();
                    corpusTagsDTO.setId(i.getId());
                    corpusTagsDTO.setParentId(i.getParentId());
                    corpusTagsDTO.setName(i.getName());
                    corpusTagsDTO.setLevel(i.getLevel());
                    return corpusTagsDTO;
                }).collect(Collectors.toList());
        // 退出递归条件,无子权限
        if (children.isEmpty()) {
            return null;
        }
        // 遍历当前所有子权限
        for (CorpusTagsDTO i : children) {
            // 开始递归查询
            i.setChildren(getChildren(trees, i.getId()));
        }
        return children;
    }

CorpusTagsDTO

@Data
public class CorpusTagsDTO {

    /** 结点ID */
    private String id;

    /** 父ID */
    private String parentId;

    /** 结点名称 */
    private String name;

    /** 深度*/
    private Integer level;

    /** 子结点 */
    private List<CorpusTagsDTO> children;

}

根据节点cId返回所有的父节点pId

public String[] selectParent(String cId) {
    //在数据库中查询
    List<Tags> trees = tagsMapper.selectList(new QueryWrapper<Tags>());
    // 根节点默认为0,即第一层权限的pid为0
    return getParents(trees,cId);
}

/**
 * 根据子节点查找父节点
 * @param trees
 * @param cId 子节点
 * @return java.lang.String[]
 */
public String[] getParents(List<Tags> trees,String cId) {
    Map<String, String> collect= trees.stream().collect(
            Collectors.toMap(
                    Tags::getId,
                    it -> (it.getParentId() == "0") ? it.getId() : it.getParentId(),
                    (v1, v2) -> v2
            )
    );
    Set<String> resSet = new HashSet<>();
    //找父节点
    findParent(resSet, collect, cId);
    String a[]=resSet.stream()
            .map(String::valueOf).sorted()
            .toArray(String[]::new);
    System.out.println(a);//["12","1201","12011"]
    return a;
}

/**
 * 路径压缩,查询父节点
 * @param orgSet
 * @param orgMap
 * @param cId 子节点
 */
private void findParent(Set<String> orgSet, Map<String,String >  orgMap , String cId) {

    if (ObjectUtil.isNotNull(cId)){
        while (!cId.equals(orgMap.get(cId))) {
            //如果不加一下判断的话,如果orgMap.get(cId))为空时(当部门有父级Id,但是父级部门又不存在数据库时),会进入死循环
            if (ObjectUtil.isNotNull(orgMap.get(cId))){
                orgSet.add(cId);
                String parent = orgMap.get(cId);
                if (ObjectUtil.isNotNull(parent)) {
                    orgMap.put(cId, orgMap.get(parent));
                    cId = parent;
                }
                orgSet.add(cId);
            }else {
                //若cId为空时则移除,当父级pId存在,但是却没有父级部门信息时,应移除pId
                orgSet.remove(cId);
                break;
            }

        }
    }
}

标签:Java,String,cId,List,trees,id,MySql,节点
From: https://www.cnblogs.com/wubalubadubdub/p/17849160.html

相关文章

  • java 将多个文件压缩成zip
    Java将多个文件压缩成zip在Java中,我们经常需要处理文件的压缩和解压缩。其中,将多个文件压缩成一个zip文件是一种常见的需求。本文将介绍如何使用Java实现将多个文件压缩成zip的功能。压缩文件的原理在开始编写代码之前,我们先来了解一下zip文件的原理。zip文件实际上是一种压缩文......
  • MySQL数据类型
    数据类型1.MySQL中的数据类型类型类型举例整数类型TINYINT,SMALLINT,MEDIUMINT,INTBIGINT浮点类型FLOAT,DOUBLE定点数类型DECIMAL位类型BIT日期时间类型YEAR,TIME,DATE,DATETIME,TIMESTAMP文本字符串类型CHAR,VARCHAR,TI......
  • MySQL约束
    约束概述:约束可以保证"数据完整性","数据的精确性"和"可靠性"。它会了防止数据库中会存在不符合语义规定的数据以及因错误输入从而导致数据错乱而提出的。在SQL规范中"约束"是对表中数据进行额外的条件限制。实体完整性:同一个表中,不能存在两条完全相同无法区分的记录。......
  • MySQL建库建表与管理
    建库建表与管理引入扩展:存储一条数据的过程。创建数据库。确认字段。创建数据表。插入数据。那我们先从创建库开始吧......
  • MySQL变量,流程控制与游标
    变量,流程控制与游标1.变量在MySql数据库的存储过程和函数中,可以使用变量来存储查询或计算中间结果数据,和输出最终的结果数据。在MySql数据库中,变量分为系统变量以及用户自定义变量。1.1系统变量1.1.1系统变量分类变量由系统定义,不是用户定义,属于"服务器"层面。启动......
  • MySQL触发器
    触发器1.触发器概述MySql从5.0.2版本开始支持触发器。MySql的触发器和存储过程一样,都是嵌入到MySql服务器的一段程序。触发器是由事件来触发某个操作,这些事件包括insert,update,delete事件。所谓事件就是指用户的动作或者触发某项行为。如果定义了触发程序,当数据库执行这些......
  • MySQL存储过程
    存储过程1.存储过程概述概述:存储过程的英文是"storedprocedure"。它的思想很简单,"就是一组经过"预先编译"的SQL语句的封装"。执行过程:存储过程预先存储在MySql服务器上,需要执行的时候,"客户端只需要向服务器端发送调用存储过程的命令",服务端就可以把预先存储好的这一系列......
  • MySQL视图
    视图(view)1.常见的数据库对象对象描述表(table)表是存储数据的单元,以行和列的形式存在,列就是字段,行就是记录数据字典(系统表)就是系统表,存放数据库相关信息的表。系统表的数据通常由数据库系统维护,程序员通常不应该修改,只能查看约束(constraint)执行数据校验的规则,......
  • 《最新出炉》系列初窥篇-Python+Playwright自动化测试-32-JavaScript的调用执行-下篇
    1.简介 在实际工作中,我们需要对处理的元素进行高亮显示,或者有时候为了看清楚操作过程和步骤我们需要跟踪鼠标点击了哪些元素需要标记出来。虽然很少遇到,但是为了以后大家可以参考或者提供一种思路,今天宏哥就在这里把这种测试场景playwright是如何处理的讲解和分享一下。2.用法......
  • Java Stream中的API你都用过了吗?
    公众号「架构成长指南」,专注于生产实践、云原生、分布式系统、大数据技术分享。在本教程中,您将通过大量示例来学习Java8StreamAPI。Java在Java8中提供了一个新的附加包,称为java.util.stream。该包由类、接口和枚举组成,允许对元素进行函数式操作。您可以通过在程序中......