【核心概念】iDempiere Data Dictionary 與 AD 體系深入解析

📚 iDempiere 開發者系列文章(3/10)- Data Dictionary 與 AD 體系深入解析

iDempiere Data Dictionary 與 AD 體系深入解析

深入解析 iDempiere 的 Data Dictionary(資料字典)AD(Application Dictionary)體系架構,是每位 iDempiere 開發者必須掌握的核心知識。AD 體系採用元資料驅動(Metadata-Driven)設計,讓你無需撰寫程式碼,即可透過設定完成資料表、視窗、欄位與選單的定義。本文將從 AD_Table、AD_Column 到 AD_Window、AD_Menu,帶你完整理解這套強大機制的運作原理。

什麼是 Data Dictionary?

Data Dictionary(資料字典)是描述資料庫結構的「元資料」集合。在傳統開發中,我們需要手動撰寫 SQL 建立資料表,再寫程式碼產生 UI 畫面。但 iDempiere 採用了革命性的設計:一切皆由 AD 表定義

資料字典包含以下資訊:

  • 資料表結構:表名、欄位名稱、資料型態
  • 欄位屬性:是否必填、預設值、驗證規則
  • 關聯關係:Foreign Key、Reference 類型
  • 顯示設定:視窗、頁籤、欄位順序
  • 選單結構:如何在系統中存取
💡 核心概念:iDempiere 的 UI 是由 AD 表「動態產生」的,不是寫死的程式碼。這代表修改 AD 設定後,畫面會立即改變,無需重新編譯部署。

AD 體系總覽

AD(Application Dictionary)體系由多個相互關聯的資料表組成,形成完整的元資料架構:

┌─────────────┐
│   AD_Menu   │ ← 選單入口
└──────┬──────┘
       │
       ▼
┌─────────────┐
│  AD_Window  │ ← 視窗容器
└──────┬──────┘
       │
       ▼
┌─────────────┐
│   AD_Tab    │ ← 頁籤(綁定 Table)
└──────┬──────┘
       │
       ▼
┌─────────────┐     ┌─────────────┐
│  AD_Field   │ ←── │  AD_Column  │ ← 欄位定義
└─────────────┘     └──────┬──────┘
                           │
                           ▼
                    ┌─────────────┐
                    │  AD_Table   │ ← 資料表定義
                    └─────────────┘

AD_Table:資料表定義

AD_Table 定義系統中的每一張資料表。當你在 iDempiere 建立新表時,首先要在這裡註冊。

欄位 說明 範例
TableName 資料表名稱 Z_BookLoan
Name 顯示名稱 圖書借閱
IsView 是否為 View N
AccessLevel 存取層級 3(Client+Org)
EntityType 實體類型 D(Dictionary)或自訂
-- 查詢特定資料表定義
SELECT AD_Table_ID, TableName, Name, Description, 
       IsView, AccessLevel, EntityType
FROM AD_Table 
WHERE TableName = 'Z_BookLoan';

AD_Column:欄位定義

AD_Column 定義資料表中的每個欄位,包含資料型態、長度、是否為主鍵等資訊。

欄位 說明 範例
ColumnName 欄位名稱 Z_BookLoan_ID
AD_Reference_ID 資料型態參照 13(ID)、10(String)
FieldLength 欄位長度 22
IsKey 是否為主鍵 Y/N
IsMandatory 是否必填 Y/N
AD_Reference_Value_ID 下拉選單參照 連結 AD_Reference
-- 查詢資料表的所有欄位
SELECT c.ColumnName, c.Name, c.AD_Reference_ID, 
       r.Name as ReferenceType, c.IsKey, c.IsMandatory
FROM AD_Column c
JOIN AD_Reference r ON c.AD_Reference_ID = r.AD_Reference_ID
WHERE c.AD_Table_ID = (SELECT AD_Table_ID FROM AD_Table WHERE TableName = 'Z_BookLoan')
ORDER BY c.SeqNo;

-- 查詢主鍵欄位
SELECT ColumnName, IsKey 
FROM AD_Column 
WHERE AD_Table_ID = (SELECT AD_Table_ID FROM AD_Table WHERE TableName = 'Z_BookLoan')
  AND IsKey = 'Y';

AD_Window:視窗定義

AD_Window 定義使用者操作的視窗容器。每個視窗可以包含多個頁籤(Tab)。

欄位 說明
Name 視窗名稱(顯示在標題列)
WindowType 視窗類型:M(維護)、T(交易)、Q(查詢)
IsSOTrx 是否為銷售交易
-- 查詢視窗定義
SELECT AD_Window_ID, Name, Description, WindowType, IsSOTrx
FROM AD_Window 
WHERE Name LIKE '%BookLoan%';

AD_Tab:頁籤定義

AD_Tab 將視窗與資料表連結。一個視窗可有多個頁籤,形成主從關係(Header-Line)。

欄位 說明
AD_Window_ID 所屬視窗
AD_Table_ID 綁定的資料表
TabLevel 頁籤層級(0=主表、1=子表…)
SeqNo 顯示順序
WhereClause 篩選條件
-- 查詢視窗的所有頁籤
SELECT t.SeqNo, t.Name, t.TabLevel, tbl.TableName
FROM AD_Tab t
JOIN AD_Table tbl ON t.AD_Table_ID = tbl.AD_Table_ID
WHERE t.AD_Window_ID = (SELECT AD_Window_ID FROM AD_Window WHERE Name = '圖書借閱')
ORDER BY t.SeqNo;

AD_Field:欄位顯示定義

AD_Field 定義欄位在頁籤中如何顯示,包括順序、是否顯示、是否唯讀等。

欄位 說明
AD_Tab_ID 所屬頁籤
AD_Column_ID 對應的欄位定義
SeqNo 顯示順序
IsDisplayed 是否顯示
IsReadOnly 是否唯讀
DisplayLogic 動態顯示邏輯
-- 查詢頁籤中的欄位配置
SELECT f.SeqNo, f.Name, c.ColumnName, f.IsDisplayed, f.IsReadOnly
FROM AD_Field f
JOIN AD_Column c ON f.AD_Column_ID = c.AD_Column_ID
WHERE f.AD_Tab_ID = ?
ORDER BY f.SeqNo;

AD_Menu:選單定義

AD_Menu 定義系統選單結構,讓使用者可以存取視窗、報表或流程。

欄位 說明
Name 選單名稱
Action 動作類型:W(視窗)、R(報表)、P(流程)
AD_Window_ID 連結的視窗
Parent_ID 上層選單
-- 查詢選單項目
SELECT m.Name, m.Action, w.Name as WindowName
FROM AD_Menu m
LEFT JOIN AD_Window w ON m.AD_Window_ID = w.AD_Window_ID
WHERE m.Action = 'W'
ORDER BY m.Name;

從 Table 到 Menu 的完整流程

建立一個新功能模組時,AD 體系的設定流程如下:

1️⃣ 建立 AD_Table
     ↓
2️⃣ 建立 AD_Column(每個欄位)
     ↓
3️⃣ 同步資料庫(Synchronize Column)
     ↓
4️⃣ 建立 AD_Window
     ↓
5️⃣ 建立 AD_Tab(連結 Table)
     ↓
6️⃣ 建立 AD_Field(從 Column 自動產生)
     ↓
7️⃣ 建立 AD_Menu(加入選單)
     ↓
✅ 完成!可以透過選單存取新視窗
💡 實務技巧:使用 Table and Column 視窗可以自動從資料庫讀取欄位結構;使用 Create Window from Table 流程可以一鍵產生視窗、頁籤、欄位。

Reference 與 Foreign Key 的關係

iDempiere 使用 AD_Reference 來定義欄位的「顯示類型」與「驗證規則」,這與資料庫的 Foreign Key 有密切關係但並非完全相同。

常用 Reference 類型

AD_Reference_ID 名稱 說明
10 String 字串
11 Integer 整數
13 ID 主鍵識別碼
14 Text 長文字
15 Date 日期
17 List 下拉選單(固定值)
18 Table 關聯資料表(Foreign Key)
19 Table Direct 直接關聯(欄位名 = TableName_ID)
20 Yes-No 布林值
30 Search 搜尋對話框

Table Direct vs Table Reference

⚠️ 重要區別:

  • Table Direct (19):欄位名必須是 XXX_ID 格式,系統自動關聯到 XXX
  • Table (18):需要額外設定 AD_Reference_Value_ID 指定關聯表和過濾條件
-- 查詢 Reference 類型定義
SELECT AD_Reference_ID, Name, ValidationType
FROM AD_Reference
WHERE IsActive = 'Y'
ORDER BY AD_Reference_ID;

-- 查詢 Table Reference 的設定(使用 AD_Ref_Table)
SELECT rt.AD_Table_ID, t.TableName, rt.AD_Key, rt.AD_Display
FROM AD_Ref_Table rt
JOIN AD_Table t ON rt.AD_Table_ID = t.AD_Table_ID
WHERE rt.AD_Reference_ID = ?;

實際範例:查詢 AD 體系 SQL

以下提供一個完整的查詢範例,從資料表追溯到選單:

-- 完整追溯:Table → Column → Tab → Field → Window → Menu

-- Step 1: 取得 Table 資訊
SELECT AD_Table_ID, TableName, Name 
FROM AD_Table 
WHERE TableName = 'Z_BookLoan';
-- 假設 AD_Table_ID = 1000000

-- Step 2: 查詢該表的所有欄位
SELECT ColumnName, Name, AD_Reference_ID, IsKey, IsMandatory, IsIdentifier
FROM AD_Column 
WHERE AD_Table_ID = 1000000
ORDER BY SeqNo;

-- Step 3: 查詢使用該表的 Tab
SELECT t.AD_Tab_ID, t.Name, t.TabLevel, w.Name as WindowName, w.AD_Window_ID
FROM AD_Tab t
JOIN AD_Window w ON t.AD_Window_ID = w.AD_Window_ID
WHERE t.AD_Table_ID = 1000000;

-- Step 4: 查詢 Tab 的欄位配置
SELECT f.SeqNo, f.Name, c.ColumnName, f.IsDisplayed, f.IsSameLine
FROM AD_Field f
JOIN AD_Column c ON f.AD_Column_ID = c.AD_Column_ID
WHERE f.AD_Tab_ID = ?
ORDER BY f.SeqNo;

-- Step 5: 查詢對應的選單項目
SELECT m.Name, m.Action, m.IsSummary
FROM AD_Menu m
WHERE m.AD_Window_ID = ?;

一次性完整查詢

-- 從 Table 一路查到 Menu 的完整關聯
SELECT 
    tbl.TableName,
    tbl.Name as TableDisplayName,
    tab.Name as TabName,
    tab.TabLevel,
    win.Name as WindowName,
    win.WindowType,
    menu.Name as MenuName
FROM AD_Table tbl
JOIN AD_Tab tab ON tbl.AD_Table_ID = tab.AD_Table_ID
JOIN AD_Window win ON tab.AD_Window_ID = win.AD_Window_ID
LEFT JOIN AD_Menu menu ON win.AD_Window_ID = menu.AD_Window_ID
WHERE tbl.TableName = 'Z_BookLoan';

常見 AD 表對照

以下整理開發時最常使用的 AD 系統表:

資料表 用途 關聯
AD_Table 資料表定義 → AD_Column
AD_Column 欄位定義 → AD_Field、AD_Reference
AD_Window 視窗定義 → AD_Tab、AD_Menu
AD_Tab 頁籤定義 → AD_Table、AD_Field
AD_Field 欄位顯示 → AD_Column
AD_Menu 選單定義 → AD_Window、AD_Process
AD_Reference 資料型態參照 → AD_Ref_List、AD_Ref_Table
AD_Ref_List 列表值定義 → AD_Reference
AD_Ref_Table 表格參照設定 → AD_Reference、AD_Table
AD_Val_Rule 驗證規則 用於動態過濾
AD_Element 系統元素(多語) → AD_Column
AD_Process 流程/報表定義 → AD_Menu

總結

iDempiere 的 AD 體系是其元資料驅動架構的核心。理解 AD_Table → AD_Column → AD_Window → AD_Tab → AD_Field → AD_Menu 的關聯,能讓你:

  • 快速建立新的功能模組而無需撰寫 UI 程式碼
  • 透過 SQL 查詢理解現有功能的結構
  • 進行客製化開發時精準定位修改點
  • 排查問題時追溯設定來源

下一篇文章,我們將實際操作建立自訂資料表與視窗,將這些理論付諸實踐!

❓ FAQ 常見問題

Q1: AD_Column 和資料庫實際欄位有什麼關係?

AD_Column 是 iDempiere 的元資料定義,需要透過「Synchronize Column」功能才會同步到實際資料庫。兩者應該保持一致,若不一致可能導致系統錯誤。

Q2: 為什麼修改 AD 設定後畫面沒有變化?

iDempiere 會快取 AD 設定。嘗試以下方法:1) 登出再登入 2) 使用「Reset Cache」功能 3) 重啟應用伺服器。開發環境可設定停用快取。

Q3: Table Direct 和 Table Reference 應該選哪個?

如果欄位名稱符合 XXX_ID 格式且直接關聯到 XXX 表,使用 Table Direct (19) 較簡單。若需要自訂過濾條件或欄位名稱不符合規則,則使用 Table (18) 並設定 AD_Ref_Table。

Q4: 如何快速建立視窗而不用一個個設定?

使用「Create Window from Table」流程,選擇目標 Table 後系統會自動建立 Window、Tab、Field。之後再微調欄位順序和顯示設定即可,大幅節省開發時間。

Q5: AD_Element 和 AD_Column 有什麼差異?

AD_Element 定義「系統元素」,提供多語系名稱和說明,是可重複使用的元件。AD_Column 則是特定資料表的欄位定義,會參照 AD_Element 取得標準名稱,但也可以覆寫為自訂名稱。


📖 iDempiere 開發者系列文章 (3/10) |
關鍵字:iDempiere, Data Dictionary, AD體系, AD_Table, AD_Column, AD_Window, 元資料驅動, ERP開發

留言

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *