在 Web 開發中,樹狀結構是常見的 UI 需求,例如部門架構、人員選擇器等。傳統做法多依賴資料庫的遞歸查詢(如 Oracle 的 CONNECT BY),但這類查詢並非所有資料庫都支援,且效能往往難以接受。本文介紹一種不依賴遞歸演算法、僅靠巧妙編碼規則與單次排序查詢即可快速構建樹結構的實戰方案。
關鍵在於單位編碼(DWBH)的設計。採用固定長度(如 10 位)的編碼,每兩位代表一級:
如此,10 位編碼天然支援五級樹結構。資料按 DWBH 排序後,父節點必定出現在子節點之前,層級關係一目了然,無需遞歸即可在單次遍歷中構建完整樹。
XT_DWCREATE TABLE XT_DW (
DWXH INT(9) NOT NULL AUTO_INCREMENT PRIMARY KEY,
DWBH VARCHAR(10), -- 10 位編碼,核心欄位
DWMC VARCHAR(30), -- 部門名稱
DWFXH INT(9) -- 父序號(若只用編碼排序,此欄可省略)
);
XT_YHCREATE TABLE XT_YH (
YHXH INT(9) NOT NULL AUTO_INCREMENT PRIMARY KEY,
YHBH VARCHAR(30),
YHMC VARCHAR(30),
DWXH INT(9), -- 關聯部門
PWD VARCHAR(20),
YHDLH VARCHAR(30)
);
String sql = "SELECT dwxh, dwbh, dwmc, dwfxh FROM xt_dw ORDER BY dwbh";
這句 SQL 幾乎通用於所有關係型資料庫,執行極快,回傳的結果集已按層級順序排列。
遍歷 ResultSet,根據 DWBH 尾部連續「0」的個數反推層級:
// 取得編碼最後一位非 0 的位置
String last = dwbh.substring(9, 10);
int i = 9;
while (last.equals("0") && i > 0) {
i--;
last = dwbh.substring(i, i + 1);
}
// 位置對應層級:1-2→1級, 3-4→2級, 5-6→3級, 7-8→4級, 9-10→5級
if (i == 0 || i == 1) level = 1;
else if (i == 2 || i == 3) level = 2;
else if (i == 4 || i == 5) level = 3;
else if (i == 6 || i == 7) level = 4;
else if (i == 8 || i == 9) level = 5;
引入 xDataTree.js 與 xtree.css,利用 JavaScript 函式 addDeptTreeNode(preLevel, curLevel, ...) 根據層級差異動態增減節點,最後 document.write(tree) 輸出完整樹狀選單。同理,查詢該部門下人員並作為葉子節點掛載。
ORDER BY 查詢 + 線性遍歷,時間複雜度 O(N)。此法在百萬級資料量下同樣表現優異,是構建高效能 Web 樹狀元件的經典實踐。