如何在 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.pswp.cn/bicheng/93111.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/93111.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/93111.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java畢業設計選題推薦 |基于SpringBoot的水產養殖管理系統 智能水產養殖監測系統 水產養殖小程序

&#x1f525;作者&#xff1a;it畢設實戰小研&#x1f525; &#x1f496;簡介&#xff1a;java、微信小程序、安卓&#xff1b;定制開發&#xff0c;遠程調試 代碼講解&#xff0c;文檔指導&#xff0c;ppt制作&#x1f496; 精彩專欄推薦訂閱&#xff1a;在下方專欄&#x1…

排序概念、插入排序及希爾排序

一、排序基本概念1.就地排序&#xff1a;使用恒定的額外空間來產生輸出就地排序只是在原數組空間進行排序處理&#xff0c;也就是輸入的數組和得到的數組是同一個2.內部排序和外部排序&#xff1a;待排序數據可以一次性載入到內存中為內部排序&#xff0c;反之數據量過大就是外…

【排序算法】④堆排序

系列文章目錄 第一篇&#xff1a;【排序算法】①直接插入排序-CSDN博客 第二篇&#xff1a;【排序算法】②希爾排序-CSDN博客 第三篇&#xff1a;【排序算法】③直接選擇排序-CSDN博客 第四篇&#xff1a;【排序算法】④堆排序-CSDN博客 第五篇&#xff1a;【排序算法】⑤冒…

Android領域驅動設計與分層架構實踐

引言在Android應用開發中&#xff0c;隨著業務邏輯日益復雜&#xff0c;傳統的MVC或簡單MVP架構往往難以應對。領域驅動設計(Domain-Driven Design, DDD)結合分層架構&#xff0c;為我們提供了一種更系統化的解決方案。本文將探討如何在Android項目中應用DDD原則與分層架構&…

Android12 Framework電話功能UI定制

文章目錄簡介代碼中間按鈕Fragment創建VideoCallFragmentFragment管理添加按鍵掛斷電話功能相關文章簡介 Android版本&#xff1a;12 芯片平臺&#xff1a;展銳 如下圖為通話中的UI&#xff0c;打電話出去時顯示的UI與此也差不多&#xff0c;但來電時UI是不一樣的 這個界面是…

高并發場景下分布式ID生成方案對比與實踐指南

高并發場景下分布式ID生成方案對比與實踐指南 在分布式系統中&#xff0c;唯一且全局有序的ID生成器是很多業務的底層組件。隨著系統并發量不斷攀升&#xff0c;如何在高并發場景下保證ID的唯一性、性能、可用性和可擴展性&#xff0c;成為后端架構師需要重點考慮的問題。本文將…

Emscripten 指南:概念與使用

Emscripten 指南&#xff1a;概念與使用 什么是 Emscripten&#xff1f; Emscripten 是一個開源的編譯器工具鏈&#xff0c;用于將 C/C 代碼編譯成高效的 WebAssembly&#xff08;Wasm&#xff09;和 JavaScript。它基于 LLVM 編譯器架構&#xff0c;允許開發者&#xff1a; ?…

使用鏡像網站 打開克隆 GitHub 網站倉庫內容 git clone https://github.com/

GitHub 網站有時因 DNS 解析問題或網絡限制&#xff0c;國內訪問可能會受限。使用鏡像網站打開網站 使用鏡像網站&#xff1a;GitHub 有一些鏡像網站&#xff0c;可替代官網訪問&#xff0c;如https://hub.fastgit.org、https://gitclone.com、https://github.com.cnpmjs.org等…

Linux隨記(二十二)

一、redhat6.5 從openssh5.3 升級到openssh10 - 報錯處理【升級后賬號密碼一直錯誤 和 sshd dead but subsys locked】 虛擬機測試情況 - 正常&#xff1a;情況一、 升級后賬號密碼一直錯誤 情況二、 執行service sshd status出現 sshd dead but subsys locked

機器學習之TF-IDF文本關鍵詞提取

目錄 一、什么是 TF-IDF&#xff1f; 1.語料庫概念理解 二、TF-IDF 的計算公式 1. 詞頻&#xff08;TF&#xff09; 2. 逆文檔頻率&#xff08;IDF&#xff09; 3. TF-IDF 值 三、關鍵詞提取之中文分詞的實現 四、TF-IDF簡單案例實現 &#xff08;1&#xff09;數據集…

Flutter屏幕和字體適配(ScreenUtil)

一、簡介 flutter_screenutil 是一個 Flutter 插件&#xff0c;專門用于處理屏幕適配問題。它簡化了不同設備間尺寸差異的處理&#xff0c;確保你的應用在各種屏幕上都能保持良好的顯示效果。開發者可以通過簡單的調用來設置基于設計圖尺寸的控件寬高和字體大小。 項目地址&a…

mimiconda+vscode

安裝miniconda實現python包管理&#xff0c;并通過vscode進行編寫python代碼 miniconda簡單介紹 Miniconda 是 Anaconda 公司的一個輕量級 Python 發行版本&#xff0c;它包含了最基本的包管理器 conda 和 Python 環境&#xff0c;只帶最核心的組件&#xff0c;沒有額外的大量科…

Windows文件時間修改指南:從手動到自動化

修改文件的時間屬性可以滿足多種需求。比如&#xff0c;它可以幫助整理文件&#xff0c;使得文件按照特定的時間順序排列&#xff0c;有助于更好地管理資料。它的體積真小&#xff0c;才300多KB。能用來調整文件的創建時間、最后訪問和修改時間。文件時間屬性修改_NewFileTime.…

能刷java題的網站

以下是一些適合刷Java題的優質網站&#xff0c;涵蓋從基礎到進階、算法面試及實戰項目等多種需求&#xff1a; ?一、綜合編程練習平臺? ?LeetCode?&#xff08;leetcode.com&#xff09; ?特點?&#xff1a;全球最知名的算法題庫&#xff0c;含海量Java題目&#xff0c;分…

掘金數據富礦,永洪科技為山東黃金定制“數智掘金”實戰營

在黃金開采的轟鳴聲中&#xff0c;另一場靜水深流的“掘金行動”正悄然展開。山東黃金集團&#xff0c;這個行業的巨頭&#xff0c;在深挖地層寶藏的同時&#xff0c;也敏銳捕捉到數據洪流中蘊藏的價值富礦。然而&#xff0c;當海量業務數據匯聚&#xff0c;如何從中精準提煉決…

【論文閱讀】BEVFormer論文解析及Temporal Self-Attention、Spatial Cross-Attention注意力機制詳解及代碼示例

BEVFormer: Learning Bird’s-Eye-ViewRepresentation from Multi-Camera Images via Spatiotemporal Transformers|Temporal Self-Attention、Spatial Cross-Attention注意力機制詳解 BEVFormer&#xff08;Bird’s-Eye-View Former&#xff09;是一種先進的計算機視覺模型&am…

在 Ubuntu 中docker容器化操作來使用新建的 glibc-2.32

在 Ubuntu 中使用容器化操作來使用新建的 glibc-2.32,可以通過創建自定義 Docker 鏡像來實現。以下是完整的解決方案: 方案 1:創建包含 glibc-2.32 的 Docker 鏡像 1. 創建 Dockerfile dockerfile # 使用 Ubuntu 基礎鏡像 FROM ubuntu:20.04# 安裝編譯依賴 RUN apt-get …

GOOUUU ESP32-S3-CAM 果云科技開發板開發指南(二)(超詳細!)Vscode+espidf 攝像頭拍攝視頻實時傳輸到LCD,文末附源碼

書接上回&#xff0c;上一篇blog是使用esp32s3通過ov2640攝像頭拍攝到一幀照片&#xff0c;并把它保存到了SD卡中&#xff0c;這第二篇就通過LCD將拍攝到的圖片顯示到LCD上&#xff0c;本次分享硬件使用的 ESP32-S3-CAM 果云科技開發板&#xff0c;并且使用了配套的LCD擴展板&a…

攻防世界-ics-05(遠程文件執行)

一.審題大致瀏覽一下網頁&#xff0c;發現就這邊會有東西。看一下源碼會不會有東西或者稍微點擊一下這個頁面的內容看會不會出現東西。點擊了一下這個云平臺設備維護中心發現url變了&#xff0c;是get的方法傳page參數二.嘗試漏洞類型自己這邊試了sql注入發現不是&#xff0c;試…

Dell PowerEdge: Servers by generation (按代系劃分的服務器)

Dell PowerEdge: Servers by generation {按代系劃分的服務器}1. Table of 17th, 16th, 15th, and 14th Generation PowerEdge servers2. List of all PowerEdge server models including Type, CPU vendor, Generation, and Remote ManagementReferencesPowerEdge: Servers by…