目錄
| - |
建立含有下拉式清單組件的頁面 |
| - |
將元件連線到資料庫 |
| - |
添加表組件 |
| - |
修改 SQL 查詢 |
| - |
控制所顯示的行 |
| - |
更多功能 |
|
|
|
在使用本教程之前,您需要在系統上安裝含有 Web 和 Java EE 支援的 NetBeans IDE 6.0。熟悉 IDE 的各個基本部分並閱讀 NetBeans 可視化 Web JSF 開發 瞭解 NetBeans IDE 開發環境的簡要介紹。
本教程將涉及以下技術和資源:
JavaServer Faces 組件 Java EE 平台 |
1.2 與 Java EE 5* 1.1 與 J2EE 1.4 |
| Travel 資料庫 |
必需 |
* 到本文發布之日時止,只有 Sun Java System Application Server 支援 Java EE 5。
本教程適用於 GlassFish V2 應用伺服器。如果使用的是不同的伺服器,請參閱 版本資訊 和 常見問題集 瞭解各類問題和解決途徑。有關所支援的伺服器和 Java EE 平台的詳細資料,請參閱 版本資訊。
建立含有下拉式清單組件的頁面
在本教程中,我們將構建一個 Travel Center 應用程式,如中部署的應用程式所示。
| 圖 1:已部署的 Travel Center Web 應用程式 |
首先,我們將在新項目建立的預設的 Page 1.jsp 頁面中添加一個 Table 組件和一個 Drop Down List 組件。
建立一個新 Web 應用程式項目,將它命名為 DataboundComponents,該應用程式使用 GlassFish V2 應用伺服器和 Visual Web JavaServer Faces 架構。
IDE 將建立第一個頁面,其名稱為 Page1,並在 Visual Designer 中顯示該頁面。
- 展開 Palette 中的 Basic 節點,然後拖動一個 Label 組件到頁面左側。鍵入
Select Name: 並按下斷行符號鍵。
- 拖動一個 Drop Down List 組件到 Label 組件右側。
- 在 Properties 視窗中,將 id 屬性修改為
personIdDD。
按住 Ctrl-Shift 鍵的同時拖動 Drop Down List 組件到 Label 組件,將這兩個組件關聯到一起。
Label 組件的 for 屬性現在已設定為 personIdDD。
從 Palette 視窗拖動一個 Message Group 組件到頁面某角落中,比如說頁面的右上方。
該組件可用於診斷編程錯誤。我們可以讓診斷訊息出現在該組件中,方法是調用 info(String)、 error(String)、 warn(String)和 fatal(String) 方法。Message Group 組件將顯示 String 參數的值。此外,關於執行階段錯誤、驗證錯誤和轉換錯誤的訊息將預設出現在該組件中。
將元件連線到資料庫
Services 視窗位於 IDE 工作空間的左側,其中含有一個 Databases 節點。Databases 節點將顯示已添加到 IDE 中的所有資料庫驅動程式和串連。
NetBeans IDE 附帶的 樣本 Travel 資料庫 出現在 Databases 節點下面。
將資料庫綁到組件時,我們將在組件和資料庫表之間建立兩個層:RowSet 層和 Data Provider 層。RowSet 層負責串連資料庫、執行查詢和管理結果集。Data Provider 層提供了一個公用介面用於訪問許多類型的資料,包括 rowsets、Array 對象和 Enterprise JavaBeans 對象。
通常,我們只有在需要設定查詢參數時才會用到 RowSet 對象。在大多數其他情況下,我們應該使用 Data Provider 對象訪問和操作資料。我們可以通過使用 Data Provider API 來降低學習門檻,因為相同的 API 適用於封裝任何類型的資料(也就是所使用的 Data Provider 實現)。
在本節中,我們將使用 Travel 資料庫中的 PERSON 表為 Drop Down List 組件提供選擇。
在 Services 視窗中,展開 Databases 節點,然後驗證是否已串連到 TRAVEL 資料庫。
如果 TRAVEL 資料庫 jdbc 節點的標誌是裂開的並且無法展開該節點,則表示 IDE 未串連到資料庫。要串連到 TRAVEL 資料庫,按右鍵 TRAVEL 資料庫的 jdbc 節點並從快顯功能表中選擇 Connect 選項。 如果出現 Connect 對話方塊, 則輸入 travel 作為使用者名稱和口令,選中 Remember Password During This Session 選項並單擊 OK 按鈕。如果未看到 TRAVEL 資料庫的 jdbc 節點,則查看 如何在 NetBeans IDE 6.0 中啟用 MySQL 樣本 Travel 資料庫 這篇文章瞭解如何將 IDE 串連到資料庫。
展開 Travel > Tables 節點。
在 Tables 節點下面,我們可以看到資料庫各個表的節點,比如說 CARRENTAL 和 FLIGHT。展開 Tables 節點的 Services 視窗如所示。
將 Services 視窗中的 PERSON 拖動到 Drop Down List 組件上。
abc 文本將出現在 Drop Down List 組件中。 abc 文本表示顯示欄位已綁定到一個 String 對象,本例中的 String 對象為 SQL 資料庫中的一列,其類型為 varchar。此外,IDE 將為資料庫表添加一個不可見的 personDataProvider 組件。personDataProvider 組件將出現在 Navigator 視窗中。IDE 還會添加一個 personRowSet 屬性到 SessionBean1 中。
按右鍵 Drop Down List 組件並從快顯功能表中選擇 Bind to Data 選項。此時將出現 Bind to Data 對話方塊,如所示。
| 圖 3:將資料繫結到 Drop Down List 組件 |
將資料繫結到 Drop Down List 組件時,我們必須指定在列表(Display Field)中顯示的內容並且還要指定底層程式(Value Field)所使用的值。通常,我們希望通過資料庫表顯示一些有意義的值,比如說某人的姓名,但是也希望在底層程式中使用惟一的標識符。但是在此應用程式中,我們希望將 Value 值和 Display 值同時綁定到資料庫中的同一列,即 PERSON.NAME 列,如以下兩個步驟所示。
- 在 Bind to Data 對話方塊中,選擇 Value Field 列表中的 PERSON.PERSONID 選項使組件的 getSelected 方法返回當前選擇的 PERSON.PERSONID。
- 選擇 Display 列表中的 PERSON.NAME,讓瀏覽器使用 PERSON.NAME 資料庫列中的值填充下拉式清單。
- 單擊 OK 按鈕。
單擊主工具列中的 Run > Run Main Project 按鈕。
IDE 將儲存所有修改,然後編譯、部署和運行應用程式。首先,Output 視窗將出現在 IDE 底部。IDE 會將編譯和部署準備資訊寫入到該視窗中。如果在編譯過程中遇到任何問題,請首先查閱 Output 視窗。接下來,對話方塊將顯示部署的狀態資訊。部署完成之後,IDE 將在 網頁瀏覽器中開啟應用程式。瀏覽器在呈現頁面時會使用 PERSON 表的 NAME 列中的資料填充下拉式清單。
添加表組件接下來,我們將在應用程式中添加一個 Table 組件並將該元件連線到一個資料庫表。
- 從 Palette 中拖動一個 Table 組件並將它放置在 Drop Down List 組件下面。
- 在 Services 視窗中,展開 Travel > Tables 節點。
將 Services 視窗中的 TRIP 拖動到 Table 組件標題列上。
注意: 如果將 TRIP 資料庫放置在表組件的其他部分上,則會開啟 Choose Target 對話方塊。在 Choose Target 對話方塊中,選擇 table1 選項並單擊 OK 按鈕。
按右鍵 Table 組件並選擇 Table Layout 選項。
Table Layout 框中的 Selected 列表將顯示表中的所有列。我們將使用 Selected 列表中的項目指定哪些列應顯示在 Table 組件中。
- 使用 Ctrl-Click 按鍵組合選擇 Selected 列表中除 TRIP.DEPDATE、TRIP.DEPCITY 和 TRIP.DESTCITY 之外的所有條目。
單擊 < 按鈕。
所選條目已全部移至 Available 列表,只有以下三個條目仍然保留在 Selected 列表中,如所示:
單擊 OK 按鈕。
此時,Visual Designer 將顯示 Table 組件中的三列資料,如所示。
修改 SQL 查詢接下來,我們將修改 tripRowSet 對象中的 SQL 查詢,使查詢也返回 TRIPTYPE 表中的資料。我們還將修改 Table 組件,在其中顯示旅行類型描述。
在 Navigator 視窗中,展開 SessionBean1 節點(如果該節點尚未展開)。
| 圖 6:Navigator 視窗中的 SessionBean1 部分 |
在 Navigator 視窗的 SessionBean1 部分,按右鍵 tripRowSet 節點並選擇 Edit SQL Statement 選項。
Query Editor 將出現在編輯匹域,其中含有一個 tripRowSet 選項卡。
技巧 :如果 Output 視窗是開啟的,則關閉它將更多的空間留給 Query Editor。
將 Services 視窗中的 Travel > Tables > TRIPTYPE 節點拖動到 Design View 中, 7 所示。< /p>已有的兩個表圖中間將出現另一個表圖,其中含有一個連結。該連結資料表示一對串連。注意 IDE 修改 Source Code 面板中選擇語句的方式。
清除 TRIPTYPE 表中的 PERSONID 複選框。
此操作將移除結果集和 SQL 查詢(即 Source Code 面板)中的列,如所示:
- 讓 Query Editor 繼續開啟。
- 單擊編輯地區中的 Page 1 選項卡。
在 Visual Designer 中,按右鍵 Table 組件並選擇 Table Layout 選項。
此時將出現 Table Layout 對話方塊,由於我們已經修改了 tripRowSet 的 SQL 查詢,因此可以顯示更多的列。
將 TRIPTYPE.DESCRIPTION 列添加到 Selected 列表中,然後單擊 OK 按鈕。
第四個列將出現在 Table 組件中。
控制所顯示的行
為 TRIP 表添加了一個 Data Provider 之後,IDE 將建立一個 RowSet 對象,其中的 SQL 查詢將為表的所有列返回所有行。如果在此時部署並運行應用程式,則 Table 組件將在 TRIP 表中顯示所有旅行資訊。
對於本文中的應用程式,Table 組件只顯示與在 Drop Down List 組件中選擇的人名相對應的旅行資訊。通過編輯 tripRowSet 對象的 SQL 查詢在 Drop Down List 組件和 Table 組件之間建立一個主從複合(master-detail)關係,我們限制了在資料庫表中顯示的資訊。
- 單擊編輯地區中的 jdbc:derby://localhost:1527/travel 選項卡,切換到 Query Editor。
- 在 Query Editor 的 Design Grid 中,按右鍵 PERSONID 行中的任何錶元並選擇 Add Query Criteria 選項。
- 將 Comparison 下拉式清單設定為
=Equals,選中 Parameter 選項按鈕並單擊 OK 按鈕。
我們可以在 PERSONID 表的 Criteria 列中看到 =?,它會在 SQL 查詢中添加以下 WHERE 語句。
| 程式碼範例 1:SQL 查詢中的 WHERE 語句 |
WHERE TRAVEL.TRIP.PERSONID = ? |
故障診斷技巧: 此時,我們可以驗證查詢是否已正確設定。在查詢編輯器中單擊滑鼠右鍵,然後選擇 Run Query 選項。在 Specify Parameters Value 對話方塊中,鍵入 1 作為 TRAVEL.TRIP.PERSONID 參數的值,然後單擊 OK 按鈕。Person 1 查詢的輸出位於查詢編輯器的結果面板中。
在 Query Editor 的 Design Grid 中,單擊 DEPDATE 行中的 Sort Type 表元並從下拉式清單中選擇 Ascending 選項。
IDE 將自動化佈建 Sort Order 並將排序語句添加到 SQL 查詢中。
- 關閉 Query Editor。
在 Visual Designer 中,按右鍵 Drop Down List 組件。
Page1 類的原始碼將在 Java Editor 中開啟,並且游標將位於 personIdDD_processValueChange 方法的主體中。IDE 將在首次雙擊 Drop Down List 組件時建立這個事件處理常式方法的主幹程式( Stub)。
將 personIdDD_processValueChange 方法的主體替換為以下黑體代碼。
| 程式碼範例 2:Drop Down List 組件的值修改事件處理 |
public void personIdDD_processValueChange(ValueChangeEvent event) { try { getSessionBean1().getTripRowSet().setObject( 1, personIdDD.getSelected()); tripDataProvider.refresh(); } catch (Exception e) { error("Cannot switch to person " + personDataProvider.getValue( "PERSON.PERSONID")); log("Cannot switch to person " + personDataProvider.getValue( "PERSON.PERSONID"), e); } }
|
以上代碼會將下拉式清單中當前所選 NAME 的 PERSONID 值綁定到 tripRowSet 對象的準備 SQL 陳述式中的參數,並執行查詢以及擷取新的結果集。
setObject 方法會將查詢中的 ? 替換為 PERSONID 的值。 refresh 方法用於提交新查詢和重新整理結果集。要瞭解有關這兩個方法的更多資訊,按右鍵方法調用並從快顯功能表中選擇 Show Javadoc 選項。查看 Data Provider 和 RowSet Javadocs,方法是選擇 Help > Javadoc References > Data Provider and Help > Javadoc References > RowSet 選項。
log 方法將發送一條訊息和關聯棧跟蹤給應用伺服器的日誌,作用是協助發現和診斷使用者問題。查看伺服器日誌的方法是按右鍵 Services 視窗中的 server 節點並從快顯功能表中選擇 View Server Log 選項。
- 按下 Alt-Shift-F 按鍵組合重新格式化代碼。
- 找到原始碼中的
prerender 方法。
將 prerender 方法的主體替換為以下黑體代碼。
| 程式碼範例 3:首次顯示頁面時同步主從資料 |
public void prerender() { if ( personIdDD.getSelected() == null ) { try { personDataProvider.cursorFirst(); getSessionBean1().getTripRowSet().setObject( 1, personDataProvider.getValue("PERSON.PERSONID")); tripDataProvider.refresh(); } catch (Exception e) { error("Cannot switch to person " + personDataProvider.getValue("PERSON.PERSONID")); log("Cannot switch to person " + personDataProvider.getValue("PERSON.PERSONID"), e); } } } |
prerender 方法中的代碼將在 網頁瀏覽器開始顯示頁面之前調用。
- 按下 Alt-Shift-F 按鍵組合重新格式化代碼。
- 單擊編輯工具列中的 Design 按鈕,返回到 Visual Designer 中。
按右鍵 Drop Down List 組件並選擇 Auto-Submit on Change 選項。
在 Projects 視窗,以下代碼將出現在 Onchange 屬性中。
| 程式碼範例 4:onchange 屬性代碼 |
webuijsf.suntheme.common.timeoutSubmitForm(this.form, 'personIdDD');
|
現在,當使用者在運行中的 Web 應用程式中修改下拉式清單時,網頁瀏覽器將自動認可頁面。
單擊主工具列中的 Run > Run Main Project 按鈕。
IDE 將儲存所有修改檔案,重新編譯應用程式將它重新部署到伺服器中。
- 從 Drop Down List 組件中選擇某個人物,查看 Table 組件是如何同步主從資料的。單擊 DESTCITY 列頭,查看 Table 組件如何對行排序。
更多功能
動手試試。添加一個 Static Text 組件到 Drop Down List 組件的右側。按右鍵 Static Text 組件,並從快顯功能表中選擇 Bind to Data 選項,然後將該組件綁定到 PERSON.JOBTITLE。運行程式並從下拉式清單中選擇不同的姓名。注意到職位名並未發生變化。這是因為應用程式需要保持 personDataProvider 與下拉式清單中的所選項目同步。將以下黑體代碼添加到 prerender 方法中並重新運行應用程式。現在,職位名應該與所選姓名一致了。
| 程式碼範例 5:同步 personDataProvider 與所選人名 |
public void prerender() { if ( personIdDD.getSelected() == null ) { try { personDataProvider.cursorFirst(); getSessionBean1().getTripRowSet().setObject( 1, personDataProvider.getValue("PERSON.PERSONID")); tripDataProvider.refresh(); } catch (Exception e) { error("Cannot switch to person " + personDataProvider.getValue("PERSON.PERSONID")); log("Cannot switch to person " + personDataProvider.getValue("PERSON.PERSONID"), e); } } else { try { // Synchronize data provider with current selection personDataProvider.setCursorRow( personDataProvider.findFirst( "PERSON.PERSONID", personIdDD.getSelected())); } catch (Exception e) { error("Cannot switch to person " + personIdDD.getSelected()); log("Cannot switch to person " + personIdDD.getSelected(), e); } } }
|
動手試試。 試著動作表的布局選項。按右鍵 Table 組件並從快顯功能表中選擇 Table Layout 選項。將 Header Text 修改為 Departure Date、Departure City、Destination City 和 Description。使用對話方塊中的 Options 表將表題設定為 Trips。選中 Enable Pagination 並將 Page Size 設定為 3。運行應用程式並查看這些修改將如何影響表的顯示方式。
注意: 如果要使用分頁選項,將以下代碼添加到 personIdDD_processValueChange 方法中的 tripDataProvider.refresh() 語句後面: tableRowGroup1.setFirst(0);。這樣將確保從下拉式清單中選擇新姓名時,第一個頁面總是會顯示出來,
動手試試。 構建一個含有 Drop Down List 組件和 Table 組件的應用程式。讓 Drop Down List 組件顯示 TRIPTYPE.DESCRIPTION。讓 Table 組件顯示所有與所選 TRIPTYPE 含有相同 TRIPTYPEID 的 TRIP 記錄。
動手試試。 您可能想希望
prerender 和
personIdDD_processValueChange 方法中的重複代碼是否會造成詳細 Rowset 重新整理兩次。答案是否定的。要示範這一點,可以添加一個
log(
method-name
) 語句到建構函式、
prerender 方法和
personIdDD_processValueChange 中。 在 Services 視窗中,按右鍵某個 server 節點 並從快顯功能表中選擇 View Server Log 選項。運行程式並選擇一個新姓名。在伺服器日誌(位於 Output 視窗)中,我們可以看到方法將按照以下順序調用:
- 建構函式
- prerender
- 建構函式
- personIdDD_processValueChange
當瀏覽器首次請求頁面時,應用程式會建立一個 Page1 執行個體並調用 prerender 方法。伺服器將發送響應(HTML 頁面),並且 Page1 執行個體將被銷毀。應用程式並不會調用值修改事件處理常式,因為應用程式只有在提交頁面時才會產生值修改事件。
從下拉式清單中選擇某個新姓名時,瀏覽器將提交頁面。IDE 將建立一個新的 Page1 執行個體,並恢複前一個執行個體的值(它們都在請求中傳遞)。因為這是一個提交事件,並且因為姓名已修改,所有應用程式將產生一個值修改事件。這樣會調用 personIdDD_processValueChange 方法,並且應用程式會重新整理 Rowset。
調用值修改事件處理常式之後,應用程式將調用 prerender 方法。由於下拉式清單現在已有選擇的值,因此應用程式將忽略 prerender 方法中的 if 部分。
結束語將組件綁定到資料庫表的步驟如下所示:
- 綁定一個組件到資料庫表,方法是將資料庫表的節點放置在組件上,或者從快顯功能表中選擇 Bind to Data 選項並從下拉式清單中選擇一個已有的 Data Provider。
- 使用 Bind to Data 對話方塊配置組件所顯示的資料庫列。對於清單類型組件,還需配置所返回的資料庫列。我們還可以使用 Table Layout 菜單操作配置哪些資料庫列將顯示在 Table 組件中。
- 要修改 RowSet 對象中的 SQL 查詢,可以在使用 Query Editor 開啟 Navigator 視窗中的 RowSet 對象。
- 調用 RowSet 對象的
setObject 方法,設定查詢參數的值。調用資料提供者的 refresh 方法,執行查詢並重新整理結果集。
- 使用 Auto-Submit on Change 菜單操作讓頁面在組件值發生變化時自動認可。
執行以下步驟同步主從組件:
- 在 Page Bean 的
prerender 方法中添加代碼,調用 RowSet 對象的 setObject 方法將查詢參數設定為一些預設值,比如說某個下拉式清單中的第一個人物。然後,調用 refresh 方法執行查詢。
- 將主結構(Master)組件綁定到 processValueChanged 方法。讓這個方法調用從結構(Detail) RowSet 對象的
setObject 方法設定新查詢參數。然後,調用 refresh 方法執行查詢。
本文摘自http://developers.sun.com.cn/Java/databoundcomponents.html