当前位置: 首页 > news >正文

如何在 Spring Boot 中设计和返回树形结构的组织和部门信息

如何在 Spring Boot 中设计和返回树形结构的组织和部门信息

文章目录

  • 如何在 Spring Boot 中设计和返回树形结构的组织和部门信息
      • 1. 需求分析
    • 一、数据库表设计
        • 1.1 `organization` 表设计
        • 1.2 `department` 表设计
        • 1.3 模拟数据
    • 二、后端设计
      • 2.1 实体类设计
        • `Organization` 实体类
        • `Department` 实体类
      • 2.2 DTO 类设计
        • `OrganizationDTO`
        • `DepartmentDTO`
      • 2.3 Service 层设计
      • 2.4 Controller 层设计
    • 三、前端请求与展示
      • 总结

在企业管理系统中,组织和部门之间通常存在层级结构,每个组织和部门都可能有多个子级和父级。这种树形结构的数据管理在很多业务场景下都十分常见,比如权限控制、员工管理等。

今天我们将深入探讨如何在 Spring Boot 中设计组织和部门表,如何在后端生成并返回树形结构数据,以及如何展示组织和部门的完整信息。

1. 需求分析

我们需要设计两个表:组织表organizations)和部门表departments)。两张表之间存在如下关系:

  • 每个组织可以有一个父组织,也可以有多个子组织,形成树形结构。
  • 每个部门属于某个组织,并且每个部门也有可能有子部门,部门之间同样需要支持树形结构。
  • 前端需要通过接口获取组织和部门的树形结构数据,后端通过递归算法构建树形层级。

一、数据库表设计

首先,我们需要设计两张表:organizationdepartmentorganization 表用于存储组织的信息,department 表用于存储部门的信息。两张表都需要支持树形结构的关系。


1.1 organization 表设计
  • organization 表用于存储组织的基本信息,并支持组织的树形层级关系。
  • 每个组织可以有一个父组织,也可以有多个子组织。
  • 通过 parent_id 字段,我们可以表示组织之间的父子关系。
CREATE TABLE `organization` (`id` BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '组织ID',`name` VARCHAR(255) NOT NULL COMMENT '组织名称',`description` VARCHAR(255) COMMENT '组织描述',`location` VARCHAR(255) COMMENT '组织位置',`parent_id` BIGINT DEFAULT NULL COMMENT '父组织ID',`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',CONSTRAINT `fk_parent_org` FOREIGN KEY (`parent_id`) REFERENCES `organization` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
1.2 department 表设计
  • department 表用于存储部门信息,支持部门的树形层级关系。每个部门也可以有一个父部门,也可以有多个子部门。
  • 同时,每个部门属于一个组织, 部门关联到一个组织。
  • organization_id 是部门所属的组织。
  • parent_id 是部门的父级部门。
CREATE TABLE `department` (`id` BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '部门ID',`name` VARCHAR(255) NOT NULL COMMENT '部门名称',`description` VARCHAR(255) COMMENT '部门描述',`employee_count` INT DEFAULT 0 COMMENT '员工数量',`organization_id` BIGINT NOT NULL COMMENT '所属组织ID',`parent_id` BIGINT DEFAULT NULL COMMENT '父部门ID',`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',CONSTRAINT `fk_org_id` FOREIGN KEY (`organization_id`) REFERENCES `organization` (`id`) ON DELETE CASCADE,CONSTRAINT `fk_parent_dep` FOREIGN KEY (`parent_id`) REFERENCES `department` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
1.3 模拟数据

接下来我们可以插入一些模拟数据,以便于我们在后续实现中测试树形结构。

-- 插入组织数据
INSERT INTO `organization` (`name`, `description`, `location`,`parent_id`) VALUES
('总公司', '总部组织', '上海', NULL);
('分公司A', '分公司A', '北京', 1);
('分公司B', '分公司B', '深圳', 1);
('分公司C', '分公司C', '杭州', 2);-- 插入部门数据
INSERT INTO `department` (`name`, `description`, `employee_count`, `organization_id`, `parent_id`) VALUES
('总部', '总部部门', 20, 1, NULL),
('人事部', '管理人力资源', 5, 1, 1),
('IT部', '技术支持部门', 10, 1, 1),
('市场部', '市场推广部门', 5, 1, 1),
('分公司A', '分公司A部门', 30, 2, NULL),
('市场部A', '市场部A', 5, 2, 5);

二、后端设计

2.1 实体类设计

在 Spring Boot 中,我们需要根据数据库表设计对应的实体类。

Organization 实体类
import javax.persistence.*;
import java.util.List;@Entity
public class Organization {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String name;private String description;private String location;@ManyToOne@JoinColumn(name = "parent_id")private Organization parent;@OneToMany(mappedBy = "parent")private List<Organization> children;@OneToMany(mappedBy = "organization")private List<Department> departments;private String createdAt;private String updatedAt;// Getters and setters
}
Department 实体类
import javax.persistence.*;
import java.util.List;@Entity
public class Department {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String name;private String description;private Integer employeeCount;@ManyToOne@JoinColumn(name = "organization_id")private Organization organization;@ManyToOne@JoinColumn(name = "parent_id")private Department parent;@OneToMany(mappedBy = "parent")private List<Department> children;private String createdAt;private String updatedAt;// Getters and setters
}

2.2 DTO 类设计

为了控制返回数据,我们使用 DTO(数据传输对象)来传递组织和部门的完整信息。

OrganizationDTO
import java.util.List;public class OrganizationDTO {private Long id;private String name;private String description;private String location;private String createdAt;private String updatedAt;private List<DepartmentDTO> departments;private List<OrganizationDTO> children;private OrganizationDetails details;public static class OrganizationDetails {private Long id;private String name;private String description;private String location;private String createdAt;private String updatedAt;}// Getters and setters
}
DepartmentDTO
import java.util.List;public class DepartmentDTO {private Long id;private String name;private String description;private Integer employeeCount;private String createdAt;private String updatedAt;private List<DepartmentDTO> children;private DepartmentDetails details;public static class DepartmentDetails {private Long id;private String name;private String description;private Integer employeeCount;private String createdAt;private String updatedAt;}// Getters and setters
}

2.3 Service 层设计

在 Service 层中,我们将组织和部门信息转换为树形结构,并填充每个节点的详细信息。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;
import java.util.stream.Collectors;@Service
public class OrganizationService {@Autowiredprivate OrganizationRepository organizationRepository;@Autowiredprivate DepartmentRepository departmentRepository;// 获取组织树形结构public List<OrganizationDTO> getOrganizationTree() {List<Organization> rootOrganizations = organizationRepository.findByParentIsNull();return rootOrganizations.stream().map(this::convertToOrganizationDTO).collect(Collectors.toList());}// 转换组织实体为组织DTOprivate OrganizationDTO convertToOrganizationDTO(Organization org) {OrganizationDTO orgDTO = new OrganizationDTO();orgDTO.setId(org.getId());orgDTO.setName(org.getName());orgDTO.setDescription(org.getDescription());orgDTO.setLocation(org.getLocation());orgDTO.setCreatedAt(org.getCreatedAt());orgDTO.setUpdatedAt(org.getUpdatedAt());// 填充子组织List<OrganizationDTO> children = org.getChildren().stream().map(this::convertToOrganizationDTO).collect(Collectors.toList());orgDTO.setChildren(children);// 填充部门树List<DepartmentDTO> departments = org.getDepartments().stream().map(this::convertToDepartmentDTO).collect(Collectors.toList());orgDTO.setDepartments(departments);// 填充详细信息OrganizationDTO.OrganizationDetails details = new OrganizationDTO.OrganizationDetails();details.setId(org.getId());details.setName(org.getName());details.setDescription(org.getDescription());details.setLocation(org.getLocation());details.setCreatedAt(org.getCreatedAt());details.setUpdatedAt(org.getUpdatedAt());orgDTO.setDetails(details);return orgDTO;}// 转换部门实体为部门DTOprivate DepartmentDTO convertToDepartmentDTO(Department dep) {DepartmentDTO depDTO = new DepartmentDTO();depDTO.setId(dep.getId());depDTO.setName(dep.getName());depDTO.setDescription(dep.getDescription());depDTO.setEmployeeCount(dep.getEmployeeCount());depDTO.setCreatedAt(dep.getCreatedAt());depDTO.setUpdatedAt(dep.getUpdatedAt());// 填充子部门List<DepartmentDTO> children = dep.getChildren().stream().map(this::convertToDepartmentDTO).collect(Collectors.toList());depDTO.setChildren(children);// 填充详细信息DepartmentDTO.DepartmentDetails details = new DepartmentDTO.DepartmentDetails();details.setId(dep.getId());details.setName(dep.getName());details.setDescription(dep.getDescription());details.setEmployeeCount(dep.getEmployeeCount());details.setCreatedAt(dep.getCreatedAt());details.setUpdatedAt(dep.getUpdatedAt());depDTO.setDetails(details);return depDTO;}
}

2.4 Controller 层设计

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.List;@RestController
@RequestMapping("/api/organizations")
public class OrganizationController {@Autowiredprivate OrganizationService organizationService;@GetMapping("/tree")public List<OrganizationDTO> getOrganizationTree() {return organizationService.getOrganizationTree();}
}

三、前端请求与展示

前端通过 GET /api/organizations/tree 请求接口,返回数据结构如下(嵌套完整组织部门信息):

[{"id": 1,"name": "总公司","description": "总部组织","location": "上海","createdAt": "2023-01-01T10:00:00","updatedAt": "2023-10-01T10:00:00","children": [{"id": 2,"name": "分公司A","description": "分公司A","location": "北京","createdAt": "2023-01-05T12:00:00","updatedAt": "2023-10-01T12:00:00","children": [],"departments": [{"id": 4,"name": "IT部","description": "技术支持部门","employeeCount": 10,"createdAt": "2023-01-10T09:00:00","updatedAt": "2023-10-01T09:00:00","children": [],"details": {"id": 4,"name": "IT部","description": "技术支持部门","employeeCount": 10,"createdAt": "2023-01-10T09:00:00","updatedAt": "2023-10-01T09:00:00"}}]}],"departments": [{"id": 1,"name": "总部","description": "总部部门","employeeCount": 20,"createdAt": "2023-01-01T10:00:00","updatedAt": "2023-10-01T10:00:00","children": [],"details": {"id": 1,"name": "总部","description": "总部部门","employeeCount": 20,"createdAt": "2023-01-01T10:00:00","updatedAt": "2023-10-01T10:00:00"}}]}
]

总结

在本文中,我们介绍了如何在 Spring Boot 中设计组织和部门表,如何处理树形结构,并通过 DTO 设计将组织和部门的完整信息传递给前端。在后端,我们使用了递归方法来构建树形数据结构,确保每个节点都包含该组织或部门的详细信息。


http://www.dtcms.com/a/329391.html

相关文章:

  • [AI React Web] E2B沙箱 | WebGPU | 组件树 | 智能重构 | 架构异味检测
  • [AI React Web] 包与依赖管理 | `axios`库 | `framer-motion`库
  • Matlab(4)
  • STM32H5 的 PB14 引脚被意外拉低的问题解析
  • STM32读内部FLASH,偶尔读取错误
  • 三、非线性规划
  • 基于C#、.net、asp.net的心理健康咨询系统设计与实现/心理辅导系统设计与实现
  • 【vue3】v-model 的 “新玩法“
  • 基于人工智能和物联网融合跌倒监控系统(LW+源码+讲解+部署)
  • 面试实战 问题二十六 JDK 1.8 核心新特性详解
  • 猫头虎AI分享:Word MCP,让AI具备Word文档操作能力,文档创建、内容添加、格式编辑等AI能力
  • 【Word VBA Zotero 引用宏错误分析与改正指南】【解决[21–23]参考文献格式插入超链接问题】
  • 基于Java的Markdown转Word工具(标题、段落、表格、Echarts图等)
  • Linux 桌面到工作站的“性能炼金术”——开发者效率的 6 个隐形瓶颈与破解方案
  • 一条n8n工作流
  • vscode+phpstudy+xdebug如何调试php
  • windows10装Ubuntu22.04系统(双系统)
  • VS2022+Qt 5.15.2+FreeCAD 0.21.2开发环境配置流程
  • C# WPF本地Deepseek部署
  • 洛谷 P2607 [ZJOI2008] 骑士-提高+/省选-
  • M4T无人机在外墙脱落监测中的应用:从被动补救到主动预防的技术革新
  • 【代码随想录day 19】 力扣 450.删除二叉搜索树中的节点
  • 从原材料到成品,光模块 PCB 制造工艺全剖析
  • hutool 作为http 客户端工具调用的一点点总结
  • PG靶机 - PayDay
  • pt-online-schema-change 全解析:MySQL 表结构变更的安全之道
  • 编程的几点感悟
  • 【工具】雀语queyu文件批量下载 文档内容复刻导出
  • LeetCode 面试经典 150_数组/字符串_整数转罗马数字(18_12_C++_中等)(模拟)(对各位进行拆解)
  • 地球磁层全球MHD模型中模拟Dst指数的半经验方法