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

如何在 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.xdnf.cn/news/17896.html

相关文章:

  • 在线 A2C实践
  • Transformer模型实现与测试梳理
  • 深入详解C语言的循环结构:while循环、do-while循环、for循环,结合实例,讲透C语言的循环结构
  • 免费专业PDF文档扫描效果生成器
  • 海洋通信系统技术文档(1)
  • uniapp授权登录
  • 比特币持有者结构性转变 XBIT分析BTC最新价格行情市场重构
  • 【计算机网络 | 第6篇】计算机体系结构与参考模型
  • TDengine IDMP 基本功能(4. 实时分析)
  • [QtADS]解析demo.pro
  • 【论文阅读笔记】Context-Aware Hierarchical Merging for Long Document Summarization
  • 【R语言】R语言的工作空间映像(workspace image,通常是.RData)详解
  • 《卷积神经网络(CNN):解锁视觉与多模态任务的深度学习核心》
  • 【完整源码+数据集+部署教程】火柴实例分割系统源码和数据集:改进yolo11-rmt
  • 【类与对象(下)】探秘C++构造函数初始化列表
  • 响应式对象的类型及其使用场景
  • WMware的安装以及Ubuntu22的安装
  • 11.用反射为静态类的属性赋值 C#例子 WPF例子
  • 第六十五章:AI的“精良食材”:图像标注、视频帧抽帧与字幕提取技巧
  • 数据挖掘常用公开数据集
  • 【KO】Android 网络相关面试题
  • Redis 核心数据结构与常用命令详解
  • Qwen-Image(阿里通义千问)技术浅析(二)
  • HTTP 协议详细介绍
  • 第6章 AB实验的SRM问题
  • elasticsearch mapping和template解析(自动分词)!
  • 何解决PyCharm中pip install安装Python报错ModuleNotFoundError: No module named ‘json’问题
  • Flink DataStream 按分钟或日期统计数据量
  • 如何在VS里使用MySQL提供的mysql Connector/C++的debug版本
  • LeetCode 刷题【40. 组合总和 II】