本教學示範使用 NetBeans IDE 6.5 與 JSF 1.2 Woodstock 元件,構建單頁面完成資料庫記錄的 創建 (Create)、讀取 (Retrieve)、更新 (Update)、刪除 (Delete)、還原 (Revert) 全功能應用。核心在於 虛擬表單 機制,精準控制驗證與提交範圍,實現複雜交互邏輯。
InsertUpdateDelete。下拉列表 (personDD) + 訊息群組 + 表格 (table1)。personDD、form1、表格內編輯元件、各功能按鈕分別 新增綁定屬性。travel 資料庫。person 表至 personDD,產生 personDataProvider/personRowSet。personDD:更改時自動提交 = true。personDD 虛擬表單 person:Participate=Yes, Submit=Yes (切換人員時提交此表單,避免觸發表格驗證)。trip 表至 table1,移除 tripid, personid, lastupdated 欄位。tripRowSet 加入條件 WHERE trip.personid = ? (參數化)。depdate, depcity, destcity 改為 文字欄位;triptypeid 改為 下拉列表 並拖入 triptype 表綁定。為表格編輯元件 (3 個文字欄位 + 1 下拉列表) 建立虛擬表單 save:Participate=Yes, Submit=No。
關鍵邏輯:personDD 切換時,呼叫 form1.discardSubmittedValues("save") 捨棄未存檔的編輯值,並重新查詢該人員行程。
personDD_processValueChange (切換人員)public void personDD_processValueChange(ValueChangeEvent event) {
Object selectedPersonId = personDD.getSelected();
try {
personDataProvider.setCursorRow(personDataProvider.findFirst("PERSON.PERSONID", selectedPersonId));
getSessionBean1().getTripRowSet().setObject(1, selectedPersonId);
tripDataProvider.refresh();
form1.discardSubmittedValues("save"); // 關鍵:清空表格編輯緩衝
} catch (Exception e) { error("Cannot switch to person " + selectedPersonId); }
}
prerender (首次載入預設第一人)public void prerender() {
if (personDD.getSelected() == null) {
try {
personDataProvider.cursorFirst();
Object firstId = personDataProvider.getValue("PERSON.PERSONID");
personDD.setSelected(firstId);
getSessionBean1().getTripRowSet().setObject(1, firstId);
tripDataProvider.refresh();
} catch (Exception e) { error("Init failed"); }
}
}
add (文字: 新增行程),事件 add_action:public String add_action() {
try {
RowKey rk = tripDataProvider.appendRow(); // 新增空列
tripDataProvider.setCursorRow(rk);
tripDataProvider.setValue("TRIP.TRIPID", 0); // 0 表示待產生
tripDataProvider.setValue("TRIP.PERSONID", personDD.getSelected());
tripDataProvider.setValue("TRIP.TRIPTYPEID", 1); // 預設類型
} catch (Exception ex) { error(ex.getMessage()); }
return null;
}
maxTripRowSet (SessionBean) 查詢 SELECT MAX(trip.tripid)+1 AS MAXTRIPID FROM trip。save (文字: 儲存更改),虛擬表單 save Submit=Yes。save_action 邏輯:取得 MAXTRIPID,遍歷 DataProvider 將 TRIPID=0 的列更新為新 ID,呼叫 tripDataProvider.commitChanges() 寫入資料庫。delete。TableRowGroup1 與 delete 按鈕新增綁定屬性。delete_action:取得 tableRowGroup1.getRowKey(),呼叫 removeRow() + commitChanges() 即時刪除資料庫記錄 (同步提交其他待存變更)。revert (文字: 還原更改),虛擬表單 add/revert/delete Submit=Yes (與新增、刪除共用一空表單)。revert_action:form1.discardSubmittedValues("save") + tripDataProvider.refresh() 重載資料庫狀態。| 觸發元件 | 提交虛擬表單 | Participate 元件 | 行為說明 |
|---|---|---|---|
| personDD | person | personDD | 切換人員,捨棄 save 表單編輯值 |
| 新增/還原/刪除按鈕 | add/revert/delete (空) | 無 | 繞過 save 表單驗證;刪除額外 commitChanges |
| 儲存按鈕 | save | 表格編輯元件 | 驗證並提交所有編輯變更 |
本教學完整展示了 JSF 視覺化開發中 DataProvider 行集操作 與 虛擬表單提交控制 的黃金搭檔。掌握 discardSubmittedValues、appendRow/removeRow/commitChanges、虛擬表單 Participate/Submit 矩陣,即可輕鬆構建複雜的主從編輯頁面,且無需撰寫繁瑣的手動狀態管理代碼。