首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

使用 Java Persistence API 與 JavaServer Faces 開發 Web 應用程式

     編輯:Java 相關知識

前言

當應用程式需要資料持久化支援時,Java Persistence API (JPA) 提供了一種簡單的方法來使用關聯式資料庫。雖然 JPA 過去常與 Enterprise JavaBeans (EJB) 搭配使用,但它也能直接應用於 Web 應用程式中。本文將介紹 IBM Rational Application Developer for WebSphere Software V7.5 所提供的簡化程式設計模型與工具,示範如何輕鬆建構使用 JPA 的 Web 應用程式。注意:本文基於 IBM Rational Application Developer V7.5 Open Beta 版本撰寫。

JPA 概述

JPA 是一種用於物件關聯映射 (ORM) 及資料持久化的簡化程式設計模型。資料持久化確保應用程式在檢索與更新資料時,能與後端資料庫的當前狀態保持同步。過去這通常透過 Java Database Connectivity (JDBC) API 與其他資料框架完成,步驟繁瑣且常需撰寫複雜的查詢語句來新增或修改資料。

JPA 透過使用資料庫表格、被存取實體的 Java 表示,以及一組支援查詢與操作資料的 API,大幅簡化了這個過程。

實體

實體物件是 JPA 應用程式中使用的主要模型。一個實體是對資料庫中資料表建模的 POJO (Plain Old Java Object)。它包含與資料表欄位對應的屬性,並允許應用程式直接與資料庫的概念模型互動。

範例

假設資料庫中有一個名為 Department 的資料表,包含 deptname 欄位。在應用程式中,會有一個對應的 Department Java 類別,包含名為 deptname 的欄位,以及相應的 getter 與 setter 方法。圖 1 展示了 Department 資料表與對應實體類別的關係。

實體映射

將實體與關聯式資料庫資訊 (如主鍵、關聯) 進行映射,可以直接在實體類別中使用 Java 註解指定,也可選擇在獨立的映射設定檔中定義。JPA 在可能的情況下,對這些資料映射使用預設值,消除了大量樣板程式碼與繁瑣的映射資訊。例如,名為 Department 的實體類別預設會與名為 Department 的資料表對應,除非需要覆寫預設值,否則無須額外定義。

檢索與持久化資料

JPA 提供了 API 來映射與持久化實體。EntityManager 類別用於檢索、持久化、更新及刪除實體。在 JPA 應用程式中,開發者直接操作實體物件,無需撰寫底層 JDBC 程式碼來插入或更新資料庫資料列。

新增資料列只需建立實體類別實例、設定屬性,並透過 EntityManager 持久化新實體。更新與刪除現有資料同樣簡單。JPA 還提供 Java Persistence Query Language (JPQL) 來查詢資料庫並檢索資料。JPQL 是一種語法類似 SQL 的完整查詢語言,但針對實體而非資料表操作。

JPQL 查詢範例

SELECT d FROM Department d ORDER BY d.deptNo

此查詢可傳遞給 Entity Manager,以依部門編號排序檢索所有 Department 實體清單。

Web 容器中的 JPA

JPA 最初作為 EJB 3.0 規範的一部分,後獨立成為獨立規範,使其能應用於任何 Java EE 環境 (如 Web 容器),甚至獨立的 Java SE 應用程式中。開發者可在偏好的環境中充分發揮 JPA 的優勢。

資源注入

Java EE 5 引入資源注入,可直接向程式碼注入資料來源、Web 服務、EJB 等 Java EE 容器資源,避免撰寫查找程式碼。並非所有 Web 容器元件都支援資源注入 (如 JSP 頁面),但以下元件支援:Servlet、Servlet 過濾器與監聽器、Taglib 標籤處理器、JavaServer Faces Managed Beans。本文稍後的範例將使用 JSF Managed Beans 中的資源注入。

Rational Application Developer 中的 JPA 工具

Rational Application Developer 提供多種工具協助 JPA 開發,包含編輯器、屬性視圖、視覺化建模圖表,可用於建立與編輯 JPA 實體類別。本文著重於協助將 JPA 整合至 Web 應用程式的視覺化工具。

提供的精靈能協助開發者完成許多若在文字編輯器中手動完成將極為耗時且易出錯的任務:

  • 視覺化配置 JPA 相關資料的工具:JPA 實體建立精靈 (基於目標資料庫結構)、JPA 實體視覺化配置、設定主鍵、設定同步化、在實體間新增/刪除關聯、新增與配置 Named Queries、視覺化 JPQL 查詢建構器 (輕鬆新增過濾條件、排序結果、撰寫投影查詢或自訂 Java 類別回傳結果)。
  • 新增與配置 JPA Manager Beans。
  • 自動為執行時期部署建構 JPA 應用程式:建立適當的 JPA 設定檔 (persistence.xml, orm.xml)、自動建立 IBM WebSphere Application Server 資料來源、獲得關聯與 Named Queries 支援。

驗證與快速修正

當 JPA 模型準備就緒,可使用額外工具簡化工作:

  • 向 Web 頁面新增 JPA 資料的工具:Palette 與 Page Data 視圖可將 JPA 資料拖曳至頁面。
  • JPA Manager Beans 提供的外觀模式服務介面。
  • 在不修改 Web 頁面程式碼前提下,變更頁面使用的查詢 (在 Web 頁面存取 JPA 資料後)。
  • 為複雜 JPA 實體新增 JSF,以及為關聯欄位新增不同 UI 控制器的工具。

JPA Manager Beans

Rational Application Developer V7.5 引入 JPA Manager Beans 概念,作為特定 JPA 實體的外觀或控制器服務 Bean。它們封裝並抽象化資料庫中用於建立、更新、刪除與顯示資訊的所有資料存取程式碼。

JPA Manager Beans 是雙層 Web 環境下的理想程式設計模型,填補了 EJB 環境下 Session Bean 的角色。所有與實體相關的業務邏輯由 JPA Manager Bean 執行。每個 JPA Manager Bean 一對一對應一個 JPA 實體。例如,Department 實體可產生名為 DepartmentManager 的 JPA Manager Bean,包含所有與該實體協同工作的資料存取邏輯 (圖 2)。

JPA Manager Beans 不限於 Web 應用程式,也可用於 EJB 專案、JPA Utility 專案或一般 Java 專案。即使 JPA 實體位於 JPA Utility 專案或 EJB 專案中,仍可為 Web 應用程式中的實體產生 JPA Manager Beans。

整合 JSF

JPA 可與 JSF Web 應用程式完美整合。JPA 實體可作為大多數 JSF 元件所需的資料繫結模型。建立或更新方案時,可輕鬆將實體繫結至輸入表單,或將實體集合繫結至 JSF 資料表以顯示資訊。

使用 JPA Manager Beans 作為程式設計模型

JPA Manager Beans 的服務導向本質,使其易於整合至服務導向架構 (SOA) 環境或設計良好的 Web 應用程式中。在這類環境下,Web 應用程式直接與 JPA Manager Bean 介面互動,Manager Bean 處理邏輯並透過 JPA API 與後端資料庫互動以檢索與更新實體 (圖 3)。此程式設計模型讓開發者專注於應用程式業務邏輯,而不陷入持久化機制細節。

使用 JSF 時,可將 JPA Manager Beans 註冊為 JSF Managed Beans,並在 Web 應用程式中直接存取。範例中,Faces 設定檔 (/WEB-INF/faces-config.xml) 在請求範圍內定義了名為 departmentManager 的 Managed Bean (圖 4、程式碼清單 1)。

<managed-bean>
 <managed-bean-name>departmentManager</managed-bean-name>
 <managed-bean-class>entities.controller.DepartmentManager</managed-bean-class>
 <managed-bean-scope>request</managed-bean-scope>
</managed-bean>

這使您能在應用程式任何地方使用 DepartmentManager Bean,無需自行實例化,因由 JSF 管理。另一優勢是允許使用資源注入,因 Bean 由 Web 容器管理。

使用 Rational Application Developer 建構 JPA Web 應用程式範例

目標

開發一個應用程式,顯示公司部門與其所屬員工,並提供更新員工資訊的功能。採用雙層架構與單一 Web 模組,包含所有 JPA 實體、JPA Manager Beans 與 Web 頁面。Web 頁面直接與資料層互動,不使用 EJB。

第一部分:建構 JPA 資料層

首先建立新的動態 Web 專案 (專案名 JpaWebExample,目標執行環境 WebSphere Application Server V7.0,Web 模組版本 2.5,設定選擇 Faces Project 以啟用 JSF)。

專案建立後,可選擇自頂向下 (資料庫表格已存在,實體基於現有結構產生) 或自底向上 (先建實體,再產生資料表) 方式。RAD V7.5 同時支援兩種方式。本範例透過建立實體與對應的 JPA Manager Beans 開始建構應用程式。

在 Enterprise Explorer 中右鍵點擊 Web 專案,選擇 JPA Tools > Add JPA Manager Beans 啟動精靈 (圖 6、7)。因尚無 JPA 實體,需點擊 Create New JPA Entities 從現有資料庫產生實體 (圖 8)。使用 RAD 內建的 Derby Sample Connection 及 SAMP 結構 (圖 9),選取 DEPARTMENT、EMPLOYEE、EMP_PHOTO 資料表產生實體。

JPA Manager Bean 精靈現顯示新建實體,選取 Department 與 Employee 實體產生對應的 Manager Beans (圖 10)。Tasks 頁面可配置主鍵、建立/編輯查詢、新增/刪除關聯、設定同步化欄位 (圖 11)。

設定主鍵與關聯

資料庫表格未定義主鍵,需手動設定:Department 實體主鍵為 deptno,Employee 實體主鍵為 empno。在 Department 與 Employee 間建立一對多雙向關聯 (一個部門有多名員工)。Employee 為關聯擁有者 (多方,包含 Department 外鍵),將 Employee 的 workdept 外鍵屬性映射至 Department 的主鍵 (圖 12)。

新增 JPA 查詢

在 Query Methods 任務頁面新增查詢方法。例如建立一個依所在地過濾並按部門名稱排序、僅回傳部門名稱與編號的查詢 (圖 13-16)。

最終產生的 JPQL 查詢:

SELECT d.deptname, d.deptno FROM Department d
 WHERE d.location LIKE 'NC' ORDER BY d.deptname

進階選項與執行時期配置

Other 任務頁面可設定 Manager Bean 名稱、啟用資源注入 (Web 容器中使用 Faces Managed Beans)、使用 Named Queries、更新實體以配合 JSF、設定關聯擷取類型 (Eager/Lazy)、配置專案 JDBC 部署 (圖 17-18)。

完成精靈後,Enterprise Explorer 顯示產生的實體與欄位、主鍵、關聯 (圖 19)。程式碼清單 2 展示 Department 實體程式碼,包含 @Entity、@NamedQueries、@Id、@OneToMany 等註解。

@Entity
@NamedQueries({
 @NamedQuery(name = "getDepartment", query = "SELECT d FROM Department d"),
 @NamedQuery(name = "getDepartmentNamesAndNumbers",
   query = "SELECT d.deptname, d.deptno FROM Department d WHERE d.location LIKE 'NC' ORDER BY d.deptname")
})
public class Department implements Serializable {
 @Id private String deptno;
 private String deptname;
 // ... 其他欄位
 @OneToMany(mappedBy="workdept", fetch=FetchType.EAGER)
 private List<Employee> employeeList;
 // ... getter/setter
}

圖 20 顯示 Page Data 視圖下的 JPA Manager Beans 概覽,包含 CRUD 操作與自訂查詢方法。程式碼清單 3 展示 DepartmentManager 程式碼,使用 @PersistenceUnit 注入 EntityManagerFactory、@Resource 注入 UserTransaction,並實作刪除、更新、查詢等方法。

@JPAManager(targetEntity=entities.Department.class)
public class DepartmentManager {
 @PersistenceUnit private EntityManagerFactory emf;
 @Resource private UserTransaction utx;
 // ... CRUD 與查詢方法
}

第二部分:向 Web 應用程式新增 JPA 資料

建立兩個 Web 頁面:listDepartments.jsp (顯示部門清單) 與 updateEmployee.jsp (更新員工資訊)。

顯示部門清單

開啟 listDepartments.jsp,從 Palette 視圖的 Data and Services 分類拖曳 JPA Data 至頁面 (圖 21)。選擇 DepartmentManager,選取 Retrieve a list of data (圖 22),選擇 getDepartmentOrdered 查詢方法 (圖 23),選擇顯示 deptno、deptname、employeeList 欄位 (圖 24),並配置 employeeList 顯示 empno、firstname、lastname (圖 25)。

生成的 JSP 程式碼將資料表繫結至 Page Code 的 getDepartmentList 方法 (程式碼清單 4),該方法取得 DepartmentManager Managed Bean 並呼叫 getDepartmentOrdered()。

@JPA(targetEntityManager = entities.controller.DepartmentManager.class,
 targetNamedQuery = "getDepartmentOrdered")
public List<Department> getDepartmentList() {
 if (departmentList == null) {
   DepartmentManager dm = (DepartmentManager) getManagedBean("departmentManager");
   departmentList = dm.getDepartmentOrdered();
 }
 return departmentList;
}

更新員工資訊

開啟 updateEmployee.jsp,拖曳 JPA Data 選擇 EmployeeManager 並選取 Update an Existing Record (圖 26)。選擇 Get Record By Primary Key (圖 27),使用 JSF 運算式 param.empno 作為主鍵值 (圖 28)。完成精靈後生成頁面與 Page Code (圖 29)。

Page Code 生成 getEmployee 方法 (程式碼清單 5) 繫結至 JSF 表單,透過 EmployeeManager 依 empno 查詢員工。updateEmployeeAction 與 deleteEmployeeAction 分別呼叫 Manager Bean 的更新與刪除方法 (程式碼清單 6)。

public Employee getEmployee() {
 if (employee == null) {
   EmployeeManager em = (EmployeeManager) getManagedBean("employeeManager");
   String empno = (String) resolveParam("employee_empno", "#{param.empno}", "java.lang.String");
   employee = em.findEmployeeByEmpno(empno);
 }
 return employee;
}
public String updateEmployeeAction() {
 EmployeeManager em = (EmployeeManager) getManagedBean("employeeManager");
 try { em.updateEmployee(employee); } catch (Exception e) { logException(e); }
 return "";
}
public String deleteEmployeeAction() {
 EmployeeManager em = (EmployeeManager) getManagedBean("employeeManager");
 try { em.deleteEmployee(employee); } catch (Exception e) { logException(e); }
 return "";
}

建立頁面導航

在 listDepartments.jsp 的 EmployeeList 資料表屬性中新增列點擊動作 (圖 30),設定導航規則至 updateEmployee.jsp (圖 31),並傳遞 empno 參數 #{varemployeeList.empno} (圖 32)。

在伺服器上執行應用程式

右鍵點擊 listDepartments.jsp 選擇 Run As > Run on Server,於 WebSphere Application Server V7.0 執行。瀏覽器顯示依部門編號排序的部門清單與員工列表 (圖 33)。點擊員工項目 (如 Christine Haas) 導航至 updateEmployee 頁面修改資訊 (圖 34),提交後返回清單頁面顯示更新結果 (圖 35)。

總結

本文介紹 JPA 提供簡單的資料持久化方式,回顧 JPA 概念與優勢,示範如何在 Web 應用程式中使用 JPA,並引入 JPA Manager Beans 處理資料持久化邏輯。IBM Rational Application Developer V7.5 提供的工具協助開發者輕鬆使用 JPA 與 JSF 建構 Web 應用程式。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved