组织机构树形结构查询


大家好,我是欧阳方超,可以扫描下方二维码关注我的公众号“欧阳方超”,后续内容将在公众号首发。
在这里插入图片描述
在这里插入图片描述

1、概述

查询目录的无限层级树形结构是一个常见的需求,比如文件管理器、网盘、公司组织机构等场景。实现这种结构需要递归遍历目录,并将目录信息组织成树形结构。这篇文章,记录了实现步骤和关键点。

2、定义表结构

假如有如下的表结构:

CREATE TABLE `t_organization` (
  `id` int NOT NULL AUTO_INCREMENT,
  `org_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '机构id',
  `org_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '机构名称',
  `p_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '上级结构id',
  `superior` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '上级机构',
  `is_valid` varchar(4) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '是' COMMENT '是否有效',
  `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '描述',
  `update_user` int DEFAULT NULL COMMENT '记录更新用户',
  `update_time` bigint DEFAULT NULL COMMENT '记录更新时间',
  `display_order` int NOT NULL DEFAULT '0' COMMENT '显示顺序',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='组织机构表';

3、Java实现

下面的代码实现了查询组织的层级结构。

/**
     * 以树形结构查询组织机构
     */
    public List<OrganizationVO>getOrgList() {
        LambdaQueryWrapper<Organization> organizationLambdaQueryWrapper = new LambdaQueryWrapper<>();
        organizationLambdaQueryWrapper.eq(Organization::getIsValid, isValid);
        List<Organization> rootOrgList = this.list(organizationLambdaQueryWrapper);
        List<OrganizationVO> organizationVOlist = new ArrayList<>();
        for (Organization temp : CollectionUtils.emptyIfNull(rootOrgList)) {
            OrganizationVO organizationVO = new OrganizationVO();
            BeanUtils.copyProperties(temp, organizationVO);
            organizationVOlist.add(organizationVO);
        }

        
        List<OrganizationVO> organizationVOresultList = new ArrayList<>();
        // 先找到所有的一级节点
        organizationVOlist.forEach(node->{
            int index = 1;
            index += organizationVOlist.stream().filter(rootNode -> node.getPId().equals(rootNode.getOrgId())).count();
            if(index == 1){ //如果没有与当前pId相等的orgId,则index仍然为1,意味着是一级节点,则将一级节点加入最后结果列表中
                organizationVOresultList.add(node);
            }
        });
        // 递归地为一级节点设置子节点
        organizationVOresultList.forEach(node->node.setChildren(childHandle(node.getOrgId(), organizationVOlist)));
        return organizationVOresultList;
    }

    //递归地获取子节点
    private List<OrganizationVO> childHandle(String orgId, List<OrganizationVO> list) {
        List<OrganizationVO> childList = new ArrayList<>();
        // 遍历所有节点,如果该节点的父类id等于orgId,则作为子节点加入当前节点中
        list.forEach(node->{
            if (node.getPId().equals(orgId)) {
                childList.add(node);
            }
        });
        // 把子节点的孩子节点循环一遍
        childList.forEach(node->node.setChildren(childHandle(node.getOrgId(), list)));
        if (childList.size() == 0) { return null; }
        return childList;
    }

4、总结

这种方式的关键点包括:
定义组织机构实体类,包含树形结构所需的属性;
从数据源查询所有部门信息;
遍历部门列表,首先构建一级节点;
为一级节点设置子节点,在该过程中递归地获取子节点;
通过这种方式,可以灵活地构建组织机构的树形结构。
我是欧阳方超,把事情做好了自然就有兴趣了,如果你喜欢我的文章,欢迎点赞、转发、评论加关注。我们下次见。

  • 9
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值