借助 NetBeans IDE 6.0 和 Visual Web 工具,您可以使用 Visual Web 數據提供程 序組件以及 Java Persistence API(JPA)來編寫連接到數據庫表的應用程序。建立了到 數據庫表的連接之後,可以使用 Java Persistence API 執行數據庫 CRUD 操作(即創建 、讀取、更新和刪除操作)。在開發基於數據庫的應用程序時,使用 Java Persistence API 能提供更高的靈活性。
本文是本系列文章的第 1 篇(共兩篇),主要介紹在 Visual Web 應用程序中使用 Java Persistence API 所需的設置步驟。您將了解如何使用此 API 連接或綁定到數據庫 表,從而能夠訪問表中的數據。在第 2 篇文章(“使用 Java Persistence API 修 改數據庫表行”)中,您將了解如何使用此 API 添加、更新和刪除數據庫表行。此 外,本文還提供了一些技巧,可以最大限度地利用 NetBeans IDE 及其可視的 web 函數 。
本文將使用以下技術和資源
JavaServer Faces 組件/
Java EE 平台
1.2/Java EE 5*
Travel 數據庫
不需要
* 要利用 NetBeans IDE 6.0 的 Java EE 5 功能,我們需要使用一個與 Java EE 5 規范完全兼容的應用服務器,比如說 Sun Java Application Server 9/GlassFish。
本文專門適用於 Sun Java Application Server PE 9.0 Update Release 1 和 Tomcat 6.0.14。如果您使用的是其他服務器,請參考 發行說明 和 常見問題解答 了解 已知問題和解決方法。有關支持的服務器和 Java EE 平台的詳細信息,請參閱 發行說明 。
概述
本文(本系列的第 1 篇文章)首先介紹了如何將 NetBeans IDE Visual Web Table 組件直接綁定到一個 Object 數組或列表(以及 POJO 或 Plain Old Java Object)。對 使用 Visual Web 工具訪問數據庫表很熟悉的開發人員一定使用過數據提供者組件。您也 許已將一個 Table 組件從 Palette 移動到一個頁面上,然後將此頁面上的數據庫表移動 到 Table 組件上。當將數據庫表移動到頁面上時,Visual Web 工具會為您創建一個數據 提供者組件,這個數據提供者處理數據庫綁定和數據訪問。
現在要將同一個 Visual Web Table 組件綁定到數據庫表,而不需要數據提供者支持 ;使用 Java Persistence API 來進行綁定。使用 JPA,可以獲得數據庫表數據並當作實 體 bean 列表或數組,然後直接將數據綁定到 Visual Web Table 組件,無需使用 ObjectListDataProvider 或 ObjectArrayDataProvider。然後可以使用 Visual Web Table 組件功能操作該數據。
除了討論 Java Persistence API 的使用之外,我們還要討論 NetBeans IDE 的一些 特性。我們將介紹如何使用 IDE 實現以下功能:
創建數據庫表、列和鍵
將一個 Visual Web 項目鏈接到一個標准 Java SE 項目,以使 web 項目能夠使用 Java SE 項目中的類。
定義一個持久單元,作為任何 JPA 應用程序的強制配置文件。
通過數據庫表生成實體類
使用 Java 源代碼編輯函數來生成代碼、修復遺失的導入語句,以及重新格式化代碼
將屬性綁定到數據
後續文章將展示如何使用指定 Visual Web 組件(比如 Grid Panel)控制頁面布局。
為何使用 Java Persistence API
Java Persistence API(在 Java EE 5 平台中引入)可用於像 web 應用程序或 EJB 這樣的企業應用程序和它們的部署到 Java EE 5 環境(如 GlassFish)或者)或 Java EE 平台外部的遠程客戶機。如果選擇 Java Persistence API,可以使用 JPA 讓應用程序繞 過 Visual Web 數據提供者組件直接與底層數據庫通信。
使用 Java Persistence API 有許多好處。第一,JPA 是一個簡單且輕量型的編程模 型,其中 POJO(plain old Java object)是“一類居民”。
將實體對象作為 POJO 處理可以引起使用 Java Persistence API 的其他好處。由於 實體是 POJO,一個實體類可以擴展另一個實體類或非實體類,一個非實體類也可以可以 擴展實體類。作為 POJO,實體類可以被序列化並通過網絡發送到其他地址空間,也可以 用於不支持持久性的環境中。從而無需使用任何特定的數據轉換對象將實體發送到遠程位 置。
借助 Java Persistence API,可以使用標准應用程序編程接口來執行與實體相關的典 型數據庫操作(Create/Read/Update/Delete 或 CRUD 操作)。還改善了應用程序的可移 植性。由於第三方持久提供者更容易為數據庫系統開發或提供插件,所以不用考慮應用程 序的可移植性就可以將不同的 Java EE 容器與不同的系統組合起來。
另外,可以使用底層數據庫的本機查詢語言來執行查詢。而且,也簡化了使用 Java Persistence API 的實體打包規則。如果應用程序具有較高的事務性需求,那麼使用 JPA 也許更好,因為它支持樂觀鎖定(也就是說,它避免了會影響到性能的鎖定),但是與其 他用戶的沖突可能會引起一些事務的失敗。
關於 Java Persistence API 的更多信息,請參閱文章 “Java Persistence API:一個更簡單的實體持久性編程模型”。
關於 Java Persistence API 的深入指導,請參閱文章 在桌面應用程序中使用持久性 API。
創建數據庫表
以下的逐步指導假設您已經設置了一個叫做 sample 的數據庫,其中包括一個叫做 Users 的數據庫表。 Users 表應該有 4 列,如下:
user_id - 主鍵;類型:整型
userName - 類型:字符串
password - 類型:字符串
email_address - 類型:字符串
執行 SQL 語句
可以使用 Services 窗口中的 Databases 節點將 Users 表添加到 sample Derby 數 據庫。可以從一個文件執行 SQL 腳本創建此表或者單獨執行每行 SQL 代碼。Services 窗口(以前稱作 Runtime 窗口)中的數據庫表節點上下文菜單函數包括用於創建新表和 執行 SQL 代碼的函數。
圖 1:SQL 執行命令
Execute Command 功能打開一個 Editor 窗口,可以向其中輸入一行或多行 SQL 代碼 。單擊 Run 按鈕執行窗口的內容。請確保 Connection 字段指示您已連接到 sample 數 據庫。
圖 2: 創建 Users 表的 SQL 代碼
定義主鍵值
可以使用以下代碼在 Derby sample 數據庫中創建 Users 表。注意子句 GENERATED ALWAYS AS IDENTITY 指示 Derby DBMS 將生成 user_id 主鍵值,並且當添加一個新紀錄 時該主鍵值自動遞增。如果向此表中手動添加記錄,比如使用 INSERT INTO 代碼,請確 保使用保留字 DEFAULT 來指示 user_id 的值是由數據庫提供的。
代碼示例 1:創建 Users 表的 SQL 代碼
create table "APP"."USERS" (
userName VARCHAR(50), password VARCHAR(12), email_address VARCHAR (50),
user_id INTEGER GENERATED always AS IDENTITY);
alter table Users add constraint usersPK PRIMARY KEY (user_id);
INSERT INTO Users VALUES ('Joe', 'joepw', '[email protected]',DEFAULT);
INSERT INTO Users VALUES ('Sarah', 'mypassword', '[email protected]', DEFAULT);
INSERT INTO Users VALUES ('Jane Doe', 'janie', '[email protected]', DEFAULT);
還有使用 Derby 定義主鍵值的其他方法。除了 Apache Derby 站點 上的 Derby Reference Manual 之外,還可以參考 Brian Leonard 撰寫的關於此項目的 博客文章。
但是請記住,不同的數據庫管理系統處理主鍵值的方式也不同。例如,對於 MySQL, 用於生成和自動遞增主鍵的表定義為:
`user_id` int(10) unsigned NOT NULL auto_increment, ...
然後,將從此數據庫表定義生成一個實體類。生成的實體類是數據庫表的 Java Persistence 表示。因為 TopLink 是 JPA 的參考實現,可以參考 TopLink 文檔 獲得關 於 id 生成的更多信息。使用 Derby,必須向生成的類手動添加注釋,以對主鍵指示生成 的值策略(@GeneratedValue))。使用 MySQL,無需在此實體類中指定生成的值策略。
將 Visual Web 項目鏈接到 Java Standard Edition 項目
要使用 Visual Web 應用程序的 Java Persistence API,實際上還需要創建兩個項目 。第一個是 Visual Web 項目。另一個是 Java Standard Edition (SE) 應用程序項目, 包括 web 應用程序將要調用其代碼的一些類。從該 Java SE 應用程序項目中生成一個持 久單元,以獲得 Java Persistence API 的一個句柄。web 應用程序然後使用在 Java SE 應用程序項目中創建的類建立數據庫綁定,隨後執行數據庫更新、刪除和添加操作。
創建項目
創建 Java SE 應用程序項目。首先創建 Java SE 應用程序項目,這是一個普通的 Java 項目。單擊工具欄上的 New Project 圖標(Ctrl+Shift+N),然後在 Categories 列表中選擇 Java,在 Project 列表中選擇 Java Application。然後單擊 Next 按鈕。
圖 3: 創建 Java 應用程序(單擊放大圖像)
在 New Java Application 窗口中,將項目名稱設置為 TestModelApp。還需要將包設 置為 com.samples.model。可以通過將默認的 Create Main Class 條目由 textmodelapp.Main 更改為 com.samples.model.Main 來實現。單擊 Finish 按鈕。
圖 4: 設置項目和包名稱
創建 Visual Web 項目。在 New Project 對話框中選擇 Web 類別,並選擇 Web Application 項目,然後單擊 Next 按鈕。
圖 5:創建 Web 項目
在 New Web Application 對話框中,將項目名稱設置為 TestWebApp。項目位置應該 默認與 TestModelApp 項目位置相同。單擊 Next 按鈕轉到下一屏幕,在其中選擇框架
圖 6: 設置 Web 項目名稱和位置
為框架選擇 Visual Web JavaServer Faces。當這樣選擇時,屏幕顯示配置設置。將 Default Java Package 設置由 testwebapp 更改為 com.samples.web。完成這一步之後 ,TestModelApp 和 TestWebApp 會作為節點出現在 Project 窗口中。單擊 Finish 按鈕 。
圖 7: 設置 Web 應用程序框架和包
將項目鏈接起來
現在需要將兩個項目鏈接起來。具體來說,需要讓 TestModelApp 作為 TestWebApp 項目的依賴項。要將 TestModelApp 作為 TestWebApp 的依賴項目,需要將 TestModelApp.jar 文件添加到 TestWebApp 項目。下面是操作方法:
在 Projects 窗口中右鍵單擊 TestWebApp 項目節點,然後從上下文菜單中選擇 Properties 選項。
在 Project Properties 對話框中,在左側的 Categories 部分單擊 Libraries 節點 。然後,單擊 Add Project 按鈕。
圖 8: 添加編譯時庫
在 Add Project 窗口,浏覽到 TestModelApp 項目的位置然後選擇它。然後,單擊 Add Project JAR Files 按鈕。此步驟將 TestModelApp jar 文件添加到 TestWebApp 項 目的運行時庫中,而且 TestModelApp 會出現在 Project Properties 屏幕中。單擊 Project Properties 屏幕中的 OK 按鈕,完成此過程。
圖 9: 添加 JAR 文件
綁定數據庫表
使用 Java Persistence API 在數據庫表和 Visual Web JSF 應用程序中使用的表可 視化組件之間傳遞信息。進行此綁定後,使用 API 獲取數據庫表的行,但是使用 Visual Web Table 組件的內置顯示功能顯示數據。
連接到數據庫
開始之前,需要將數據庫連接到 TestWebApp 項目中的 Users 表。如果使用示例 Derby 數據庫而且還沒有與之連接,那麼打開 Services 窗口,展開 Databases 節點, 打開 jdbc:derby://localhost:1527/sample [app on APP] 節點的上下文菜單並選擇 Connect。如果使用不同的 DBMS,那麼如果需要,可以為數據庫設置一個驅動程序,並根 據必須的連接參數創建一個新連接。(如果將數據庫名稱作為示例,將會更加容易執行剩 下的步驟)。
如果還未創建 Users 表,那麼現在是時候創建了:參閱 創建數據庫表。
在 Services 窗口驗證到數據庫的連接是否建立。打開 Databases > sample database Tables 節點並驗證 Users 表是否正確。 創建表示 Users 數據庫表的 Java 持久實體類
創建一個表示 Users 表的實體類。正如前面提到的,實體類是數據庫表定義的 Java Persistence 表示。JPA 使用 Java 語言注釋功能將 POJO 標記為帶有對象關系映射信息 的 JPA 實體。使用 Entity Classes from Database 函數在 TestModelApp 中創建實體 類。
在 Projects(或 Files)窗口中右鍵單擊 TestModelApp 項目。從上下文菜單中選擇 New > Entity Classes from Database 選項。
此時將顯示 New Entity Classes from Database Database Tables 對話框。如果 Database Connection 字段是空的,則從下拉列表中選擇示例數據庫。Available Tables 列顯示示例數據庫中的所有表,包括 Users 表。選擇 USERS 表並單擊 按鈕Add 將 Users 移動到 Selected Tables 列。移動 Users 表後單擊 Next 按鈕。
圖 10: 為實體類選擇數據庫表
此時將出現 Entity Classes 對話框。IDE 顯示數據庫表名稱 Users,並建議一個類 名 Users。(如果需要,雙擊類名進行更改)。對話框還指示包為 com.samples.model。 單擊 Create Persistence Unit 按鈕。
圖 11: 創建持久單元
創建持久單元
在 Create Persistence Unit 對話框中,將 Persistence Unit Name 設置為 samplePU。保留其他字段的默認值。單擊 Create 按鈕,然後在 Entity Classes 屏幕中 單擊 Finish 按鈕完成操作並創建 samplePU 持久單元。
圖 12: 為持久單元命名
驗證持久單元是否正確創建,這是一個不錯的想法。為此,展開 TestModelApp Source Packages > META-INF 節點並雙擊 persistence.xml 文件。Design 窗口將顯 示關於持久單元的信息,而 Navigator 窗口將顯示 XML 屬性。
圖 13: 驗證持久單元
單擊 XML 標簽查看完整的 XML 清單。文件中的屬性應該正確反射到數據庫名稱、url 、驅動程序、密碼,以及包和類名(com.samples.model.Users)。事務類型為 RESOURCE_LOCAL,提供者為 oracle.toplink.essentials.PersistenceProvider。重點注 意:確保正確填寫了密碼字段。
圖 14: 持久單元 XML 定義
使用 JPA 設置鍵屬性
如果使用的是 Derby 數據庫,需要對生成的 Users.java 代碼進行一些修改,以處理 主鍵值的自動生成。但是,其他數據庫系統可以以不同的方式處理主鍵值生成,對生成的 Users.java 類所做的任何修改都必須與底層數據庫的主鍵生成策略匹配。
@Id 和 @GeneratedValue 注釋
創建 Users 實體類之後,需要修改該類,以便讓數據庫自動生成主鍵字段(用戶 id 字段)。JPA 使用 @Id 注釋標識主鍵。向主鍵添加第二個注釋,指示生成主鍵值的策略 :@GeneratedValue(strategy=GenerationType.<...>),其中策略子句是可選的。 注意,選擇的生成策略必須與數據庫的性能相關聯。
使用 Derby 數據庫生成主鍵值
因為 Derby 數據庫支持 IDENTITY 列類型,因此可以為主鍵生成一個惟一值,這個任 務可以由數據庫來完成。因此,向主鍵定義中添加以下代碼行:@GeneratedValue (strategy = GenerationType.IDENTITY).
進行修改之後,定義表的 Users.java 代碼應該如下所示:
代碼示例 1:經過修改的 Users.java 類
public class Users implements Serializable {
使用 Fix Imports 功能
@Column(name = "USERNAME")
private String username;
@Column(name = "PASSWORD")
private String password;
@Column(name = "EMAIL_ADDRESS")
private String emailAddress;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "USER_ID", nullable = false)
private Integer userId;
...
注意 @GeneratedValue 標記需要兩個類:javax.persistence.GeneratedValue 和 javax.persistence.GenerationType。使用 Fix Imports 函數導入這些類。右鍵單擊源 代碼編輯窗口的任何地方,並從彈出菜單選擇 Fix Imports。Fix Imports 函數將這兩個 導入語句添加到類:
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
正如上面提到的,其他數據庫可能需要對 Users.java 代碼進行不同的修改,或者根 本不作修改。例如,對於 MySQL 數據庫,不需要包含 @GeneratedValue 注釋,因為如果 在創建表定義時為 user_id 列指定了 auto_increment,數據庫會自動生成主鍵值。
創建類
創建實體控制器類
繼續在 TestModelApp 項目中操作,在 com.samples.model 包中創建一個叫做 UserController 的新類。(我們將在下面提供此類的代碼,可以將它粘貼到您的類中) 。
展開 TestModelApp > Source Packages > com.samples.model 節點。注意包 中已經有兩個類:Main.java 和 Users.java。右鍵單擊 com.samples.model 節點並選擇 New > Java Class 選項。在 New Java Class 對話框中,將類名稱設置為 UserController(將其位置保留為 Source Packages 並將包名稱保留為 com.samples.model)。
圖 15: 創建 UserController 類
在 Edit 窗口中應該可以看見源代碼框架。向類添加如下代碼:
代碼示例 2:UserController 代碼
private EntityManagerFactory emf;
private EntityManager getEntityManager() {
if(emf == null){
emf = Persistence.createEntityManagerFactory("samplePU");
}
return emf.createEntityManager();
}
public Users[] getUsers() {
EntityManager em = getEntityManager();
try{
javax.persistence.Query q = em.createQuery("select c from Users as c");
return (Users[]) q.getResultList().toArray(new Users[0]);
} finally {
em.close();
}
}
使用 Fix Imports 函數導入需要的類。(在源代碼編輯窗口中右鍵單擊,從彈出菜單 選擇 Fix Imports 選項)。這樣可以將以下 3 個導入語句添加到類中:
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
可以使用 Format 函數(在同一個彈出菜單中)設置代碼對齊的格式。
注意 UserController 類包含方法 getUsers,該方法調用 javax.persistence.EntityManager 接口上的 createQuery 方法創建一個查詢,該查詢 從 Users 表返回數據的行。查詢的結果作為一個數組返回。
將實體 bean 綁定到表組件
您已經將用於訪問 Users 數據庫表的實體組件綁定到 TestWebApp 項目中的一個 Table 組件。(實體 bean 是在 TestWebApp 中創建的)。在 TestWebApp 項目中進行此 綁定。
下面是綁定步驟:
在 SessionBean1 中創建一個返回 Users 對象數組的屬性。
創建一個方法初始化數組。
然後,將 Users 對象數組綁定到 Table 組件。
使用 Java Persistence API Entity Manager 調用 Users 數組初始化方法。
接下來更仔細地討論一下這些步驟:
在 Session Bean 中創建一個屬性
在 NetBeans IDE 中,可以在一些位置找到托管 bean:在 Navigator 窗口,在 Projects 窗口的源代碼包節點中,以及在 Files 窗口的 src > java > project -name 節點中。
在 SessionBean1 中創建一個返回 Users 對象數組的屬性。在 Navigator 窗口中, 雙擊 SessionBean1 在 Java Source Editor 中打開。或者,從 Projects 窗口 TestWebApp > Source Packages > com.samples.web 節點中雙擊 SessionBean1。 如果沒有看到 Navigator 窗口,那麼嘗試在 Design 窗口顯示 TestWebApp 的一個頁面 ,比如 Page1。Navigator 窗口應該顯示在 Projects 窗口的下面。如果還是看不到 Navigator 窗口,在 Design 窗口單擊 Design 標簽。
向 SessionBean1 添加一個 users 屬性。鍵入以下代碼:private Users[] users;
修復導入。剛輸入的代碼很可能被標記為錯誤。如果是這樣,使用源代碼編輯器的上 下文菜單 Fix Imports 函數來修復此錯誤。(確保在繼續之前改正這個錯誤)。要修復 此錯誤,添加以下導入語句: import com.samples.model.Users;
為 users 屬性生成 get 和 set 方法。右鍵單擊鍵入的代碼行並選擇 Insert Code 動作。從彈出菜單選擇 Getter 和 Setter。然後,選擇 users:Users[]。
圖 16: 向 SsessionBean1 添加用戶屬性
使用 Insert Code 動作添加公共的 get 和 set 方法。完成之後,SessionBean1 應 該包含以下代碼:
代碼示例 3:用戶屬性的 get 和 set 方法
private Users[] users;
創建初始化方法
public Users[] getUsers() {
return users;
}
public void setUsers(Users[] users) {
this.users = users;
}
向 SessionBean1 添加一個 updateUsers 屬性。此方法將用來初始化 users 屬性。 以下是此方法的代碼:
代碼示例 4:updateUsers 方法
public void updateUsers(){
UserController usersController = new UserController();
users = usersController.getUsers();
}
使用 Fix Imports 函數修復 updateUsers 需要的導入。如果代碼中包含錯誤,執行 Save All files 清除這些錯誤。
將 updateUsers 方法的調用添加到 SessionBean1 init 方法中:updateUsers ();.SessionBean1 init 方法應該如下所示(未顯示注釋行):
代碼示例 5:SessionBean1 init 方法
public void init(){
super.init();
try {
_init();
} catch (Exception e) {
log("SessionBean1 Initialization Failure", e);
throw e instanceof FacesException ? (FacesException) e: new FacesException(e);
}
updateUsers();
}
保存所有文件。
構建 TestModelApp 和 TestWebApp 項目。
將屬性綁定到表組件
現在已經將剛添加的 users 綁定到一個 Table 組件了。
在 TestWebApp > Web Pages 中,雙擊 Page1.jsp 在 Design 窗口中打開此頁面 。
將 Table 組件從 Palette 拖到 Design 窗口中的頁面上。應該如下圖所示:
圖 17: 向 Page1 添加 Table 組件
右鍵單擊頁面上的 Table 組件並在上下文菜單中單擊 Bind to Data。在 Get Data From 下拉列表中選擇 users(從 SessionBean1)作為綁定數組。(注意如果在下拉列表 中沒有 users 屬性,右鍵單擊 Design 窗口並單擊上下文菜單中的 Refresh 選項。或者 在工具欄上單擊 Refresh 按鈕。如果還是未在下拉列表中看到 users 屬性,那麼選擇並 重新打開 TestWebApp 項目)。單擊 OK 按鈕。
圖 18:在 Bind to Data 對話框中選擇用戶
Design 中顯示的 Table 組件的更改如下。如果需要,調整顯示的列。
圖 19: Design 窗口中綁定到用戶數組的 Table 組件
部署和運行 TestWebApp 項目。顯示 Table 組件,並且如果為數據庫表創建了示例數 據庫,那麼數據應該顯示為如下形式:
圖 20: 浏覽器中 Page1 上的 Table 組件
結束語
本文討論了使用 Visual Web 應用程序的 Java Persistence API 的必要步驟。展示 了如何設置 Java SE 項目和 Visual Web JSF 項目並將它們鏈接起來。也展示了如何創 建數據庫表和需要的鍵,以及使用 Java Persistence API 綁定到數據庫。本文提供了訪 問數據庫表所需的定制 Java 代碼,此代碼演示了如何創建實體 bean 保存表數據。最後 ,還展示了如何將實體 bean 綁定到 Visual Web Table 組件,以及 Table 如何簡化數 據庫表數據的顯示。