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 類型
- 顯示設定:視窗、頁籤、欄位順序
- 選單結構:如何在系統中存取
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(加入選單)
↓
✅ 完成!可以透過選單存取新視窗
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開發
發佈留言