當您需要應用程序支持數據時, Java™Persistence API (JPA)為使 用關系型數據庫提供了一個簡單的方法。盡管過去 JPA 一直與 Enterprise Java™Beans (EJBs)一起使用,但是 JPA 與 Web 應用程序一起直接使用 也十分方便。本篇文章描述了 IBM® Rational® ApplicationDeveloper for WebSphere® Software V7.5 提供的簡化程序模型與工具,它們能方便地 構建使用 JPA 的 Web 應用程序。注意:本篇文章基於 IBM Rational Application Developer V7.5 Open Beta 版。
通過本文的姐妹篇 “使用 IBM Rational Application Developer V7.5 中的 JPA,Ajax 與 Dojo 工具開發 Web 2.0 應用程序”,了解怎樣使用 IBM Rational Application Developer V7.5 中的 JPA、Ajax 和 Dojo 工具,來創建一個端到 端的 Web 應程序。
您還可以查看 “產品演示:在 IBM Rational Application Developer V7.5 中使用 JPA 支持”,本次演示將介紹 IBM Rational Application Developer V7.5 新特性之一,對 Java 持久性 API (JPA, Java Persistence API) 的支持。
Java™Persistence API (JPA)是使用關系型數據庫的 Java 模型對象支持的規格說明。本篇文章給您一 個關於 JPA 的概述,並向您展示它怎樣在 Web 應用程序環境下運行,以及怎樣 使用 Rational Application Developer V7.5 應用 Java™Server Faces (JSF)來構建 JPA Web 應用程序。
JPA 的概述
JPA 是一個用於 對象關系映射以及數據支持的簡化程序模型。數據支持確保檢索數據與更新數據 的應用程序,在後端數據庫的當前狀態下,被同時保存。在過去,這是通過使用 Java Database Connectivity (JDBC) APIs 與 其他的數據框架來完成的,通 常這些步驟相當繁瑣,並涉及到書寫復雜的查詢語句,以添加或修改數據。
通過使用您數據庫表,被訪問實體的 Java 代表,以及提供一系列的 APIs 以 支持和查詢數據,JPA 簡化了這個過程。
實體
實體對象是 JPA 應用程序中使用的主要模型。一個實體是數據庫中為表格建 模的 POJO(Plain Old Java Object)。它包含了與表格列相對應的屬性,並允 許應用程序直接與數據庫的概念模型相聯系。
范例
這是一個包含 deptname 列的名為 Department 的數據庫。在應用程序中,有 一個相對應的名為 Department 的 Java 類,還包含了一個名為 deptname 的區 域名,以及 正確的 get 與 set 方法。圖 1 顯示出了整個的 Department 表, 以及相應的實體類。 圖 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 實體的列表 ,該列表通過它們的 department 號碼進行排序。
Web 容器中的 JPA
JPA 最初准備作為 EJB 3.0 規格說明的一部分,但是最後單獨成為一個獨立 的規格說明,因此允許其他領域利用這個優點。這意味著 JPA 可以用於任意 Java EE 環境中,例如 Web 容器,或者甚至獨立 Java SE 應用程序中。您可以 充分利用 JPA 的益處,以及它提供的便利之處,不管您喜歡什麼環境。
引入資源
在 Java Enterprise Edition 5 (Java EE)中,另一項用於簡化編程任務的 方法,是引入資源,可以直接向您的代碼,進行一次 Java EE 容器引入資源,例 如數據源,Web 服務以及 EJBs。這就避免了書寫處理一些任務所需要的代碼。
不是所有的 Web 容器組件都支持資源引入。例如,您不能在一個 JSP 頁面中 直接使用它。以下 Web 組件支持資源引入:
Servlets
Servlet 過濾器與接收器
Taglib 標簽處理器
JavaServer Faces Managed Beans
本篇文章稍後介紹的應用程序范例,將使用 JavaServer Faces Managed Beans 中的資源引入。
Rational Application Developer 中的 JPA
Rational Application Developer 提供多種工具,以幫助JPA 開發。您可以 使用編輯器,屬性視圖以及可視化建模圖表,來創建並編輯 JPA 實體類。本篇文 章將重點放在,能幫助將 JPA 集成到 Web 應用程序中的可視化工具上。
Rational Application Developer 提供能夠方便開發員完成許多項任務的向 導,如果在一個文本編輯器中去完成這些任務,將會非常耗時並容易出錯。
可視化配置與 JPA 相關數據的工具:
JPA 實體創建向導,它使用目標數據庫計劃
JPA 實體的可視化配置
設置主要關鍵字
設置同步性
在實體間添加以及刪除關系
添加並配置 Named Queries
可視化 JPQL 查詢構建器
輕松為您的查詢添加過濾器
為您的結果排序
書寫通用查詢語句以檢索個人列,或者以用戶指定的 Java 類形式返回結果
添加並配置 JPA Manager Beans
自動為運行時部署建立您的 JPA 應用程序
建立合適的 JPA 配置文件
自動創建一個 IBM WebSphere Application Server 數據源
獲得關系以及已命名查詢的支持
驗證以及快速配置
當您已經准備好您的 JPA 模型後,可以使用額外的工具,使您的工作變得更 加輕松,如下面的列表所示。
向 Web 頁面添加 JPA 數據的工具:
Palette 以及 Page Data 視圖,在這裡您可以向您的頁面添加 JPA 數據
JPA Manager Beans 提供的外觀模式,用於服務方式
在不涉及 Web 頁面代碼的前提下,那些頁面使用的能方便改變查詢的工具( 在您的 Web 頁面訪問 JPA 數據以後)
為復雜 JPA 實體添加 JSF,以及為關系區域添加不同 UI 控制器的工具
向 Web 頁面添加 JPA 數據
在一個 Web 應用程序中直接使用 JPA 是非常容易的,如果您熟悉雙層 Web 應用程序編程,或者不需要 EJBs 復雜性的話,使用 JPA 更加明智。JPA 規格說 明不需要在 Java Archives,或者 JARs (因為它們必須在 EJB 環境中)中包裹 的實體,因此,JPA 實體類可以在您的 Web 應用程序中被釋放。這自然與傳統的 Web 應用程序模型相符。
JPA Manager Beans
Rational Application Developer V7.5 引入了 JPA Manager Beans 的概念 ,它是作為外觀或者一個特定 JPA 實體的控制器的 service beans。它們使用 JPA 實體裝入並抽象出所有的,您的數據庫中用於創建,更新,刪除以及顯示信 息的數據訪問代碼。
JPA Manager Beans 是一個在雙層 Web 環境下使用的理想編程模型。它們填 充了正常條件下是由 EJB 環境下 session bean 填充的角色。所有與實體相關的 業務邏輯,是由 JPA Manager Bean 運行的。
JPA Manager beans 一對一地映射一個 JPA 實體。例如,如果您有一個 Department 實體,在 Rational Application Developer V7.5 中提供的工具, 可以用於創建一個名為 DepartmentManager 的 JPA Manager Bean,它包含了所 有需要與該實體協同工作的數據訪問邏輯(圖 2)。
圖 2. DepartmentManager 默認方法
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),來檢 索以及更新實體。該編程模型能讓您將重點集中於應用程序的業務邏輯上,而不 陷入支持機理的細節中去。
圖 3. 應用程序流范例
當使用 JSF 技術時,您可以將您的 JPA Manager beans 注冊為 JavaServer Faces-managed beans,並在您的 Web 應用程序中直接訪問它們。在接下來的例 子中, Faces 配置文件(/WEB-INF/faces-config.xml)在需求范圍內(見於圖 4 以及列表 1)包含了一個 managed bean, DepartmentManager。
圖 4. JPA Manager Bean 被定義為一個 Managed Bean
列表 1. 定義 Managed Bean 的代碼
<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 管理的。另一個使用 managed beans 帶來的 優勢是,它允許您使用資源注入,因為 bean 是由 Web 容器管理的。
使用 Rational Application Developer 構建一個 Web Application with JPA 的范例
目標:您將開發一個應用軟件,該軟件能顯示出公司部門以及它們分配的員工 。您還要增加軟件的功能,使其能夠在文件中更新所有雇員的信息。您將使用帶 單個 Web 模型的雙層結構,該單個 Web 模型包含了所有的 JPA 實體,JPA Manager Beans 以及 Web 頁面。您的 Web 頁面將與數據層直接交流,而不使用 EJBs。
在本例的第一部分,通過構建 JPA 實體與 JPA Manager Beans,您將構建您 的數據層,以和備份 Derby 數據庫相交流。在第二部分中,您將重點放在 Web 頁面中使用那些 JPA 元素。
第一部分. 建立使用的 JPA 數據
首先,您需要創建一個新的動態 Web 項目。
在菜單欄中,選擇 File > New > Dynamic Web Project。
這將啟動 Dynamic Web Project 向導(圖 5)。
圖 5. 創建新的動態 Web 項目
輸入 JpaWebExample 作為項目名。
設置目標運行時為 WebSphere Application Server V7.0 (它包含了 JPA 設 置),並設置 Web Module 版本為 2.5 。
在 Configuration 拉下菜單中,選擇 Faces Project 以能夠在您的項目中使 用 JavaServer Faces。
點擊 Finish 。
在創建 Web 項目之後,您已經為向您的應用軟件添加 JPA 數據做好了准備。 在您的應用軟件中,您可以選擇自定向下方式以創建您的實體。這意味著您的數 據庫表已經存在,而且您的實體將基於它們已存在的方案生成。在另一個概述中 ,您也可以使用 自底向上 方式來開發,在這種方式中,您首先要創建您的實體 對象,然後從實體中構建數據庫表。Rational Application Developer V7.5 同 時支持兩種方式。
通過創建實體對象以及它們相應的 JPA manager beans,您將開始構建您的應 用程序。
在 Enterprise Explorer 中右擊 Web 項目並選擇 JPATools > Add JPA Manager Beans (見於圖 6)。
圖 6. 啟動 JPA Manager Bean 向導
JPA Manager Bean 向導將顯示出項目中所有已存在的實體,或者 classpath 中所有的 Utility 項目(圖 7)。
圖 7. JPA Manager Bean 向導
現在您還沒有任何 JPA 實體,所以您需要從一個已存在的數據庫中生成實體 。
點擊 Create New JPA Entities 按鈕。
在打開 Generate Entities 向導後,在向導中(圖 8),您可以選擇一個對 某個數據庫已存在的鏈接(或者創建一個新鏈接)。
圖 8. 生成 JPA 實體
您將使用 Rational Application Developer V7.5 提供的 Derby Sample Connection。
選擇 Derby Sample Connection 以及 SAMP 方案,然後點擊 Next 。
在第二頁面中,所有數據庫鏈接可用的表格被顯示出來(圖 9)。對於本應用 軟件,您只關注部門,員工以及員工照片表。因此,您只需為這些表格構建實體 。
選中 DEPARTMENT ,EMPLOYEE,以及 EMP_PHOTO 復選框,然後點擊 Finish 。
圖 9.選中表格以生成實體
JPA Manager Bean Wizard 現在顯示出新創建的實體,接下來您需要生成相應 的 JPA Manager Beans(圖 10)。
圖 10. 選擇實體以構建 JPA Manager Beans
選擇 Department 以及 Employee 實體,然後點擊 Next 以繼續翻到向導的下 一頁。
Tasks 頁面顯示出 manager beans 和目標實體可以配置的各種設置(圖 11) 。您可以設置主要關鍵字,創建並編輯查詢,添加並刪除關系,以及設置一個同 步列。
圖 11. JPA Manager Bean 任務
您的數據庫表還沒有定義的主要關鍵字,所以現在您需要設置它們。
在主要關鍵字 Tasks 頁面中,選擇 deptno 以作為 Department 實體的主要 關鍵字。
點擊 Employee 實體,並選擇 empno 作為它的主要關鍵字。
然後點擊 Department 實體。
可能您想要在 Department 與 Employee 之間構建一對多關系(因為一個部門 擁有多名員工)。例子中的數據庫沒有詳細地定義這種關系,所以現在您需要向 您的實體添加關系。
選擇位於左列的 Relationships 任務,並點擊 Add 以啟動 Add Relationship 目錄(圖 12)。.
圖 12. 添加一個關系
從下拉菜單中選擇 Employee。設置多樣性為 one-to-many,然後選擇一個 bidirectional 關系。
“Employee”是這個關系的所有者(這就是說, Employee 是 many 邊的,因 為它包含了 Department 的外部關鍵字)。因此您需要將 Employee 的外部關鍵 字屬性,與 Department 的主關鍵字映射上。
在表格的 Employee Foreign Keys 列中選中 workdept 屬性,並點擊 OK 以 創建關系。
怎樣添加 JPA 查詢
讓我們看一下 JPA 查詢是怎樣添加的。
點擊 Query Methods 任務。本頁面顯示出了所有的,將會在您的 JPA Manager Bean 中生成的 Query Methods。
提示:點擊每個 Query Method 將會顯示出 JPQL 查詢,該查詢當您運行該方 法時會隨之運行 (圖 13)。
圖 13. Query Methods 任務
您可以添加新方法,以符合您的應用軟件的用例。為了查看一個范例,創建一 個返回部門號以及部門名,由部門所在地過濾結果的查詢。
點擊 Add 以啟動 Add Query Method 目錄(圖 14)。
圖 14. Query Method 構建器
將您的查詢名更改為比默認值更具有描述意義的值: getDepartmentNamesAndNumbers。
在標簽 Result Attributes 之下,取消對除“deptname”與“deptno”之外 所有屬性的選擇。該查詢只從數據庫中返回這兩個屬性。
目錄底部的 Query Statement 區域,顯示出了實際生成的 JPQL 查詢,該區 域會不斷更新以反映目錄的當前狀態。您也可以直接在此文本區域編輯該查詢。
切換至 Filter Results 標簽,並點擊綠色加號按鈕,以向您的查詢添加一個 過濾器。該操作會啟動 Add Filter Condition 目錄(圖 15)。
圖 15. 添加一個查詢過濾器
對於本次練習,假設您對展示位於北卡羅來納州的部門感興趣。
選擇 location 作為用做過濾器的屬性。
選擇 LIKE 作為過濾器操作符。
選擇 Constant/Entity Attribute 按鈕並輸入 NC 作為值。
點擊 OK 以向列表添加查詢語句。
提示:
您還可以選擇,如果您不想硬碼狀態名,您可以使用一個變量,並動態的將此 變量在查詢運行時,傳遞給查詢方法。
最後,點擊 Order Results 標簽,以讓您得到的結果按您想要的方式進行排 序(圖 16)。
圖 16. 向查詢添加一個 OrderBy
整理部門名,讓您得到的結果按照字母順序進行排序。
從 Available Attributes 列表中選擇 deptname,並點擊 Order 。
在 Add Query Method 條目中中點擊 OK 。
這就是最終您創建的查詢:
SELECT d.deptname, d.deptno FROM Department d
WHERE d.location LIKE 'NC' ORDER BY d.deptname
為了看到額外的高級選項,點擊Other任務(圖 17)。
圖 17. 高級選項
在本頁面中,您可以設置您的 manager bean 的名字,並考慮以下高級選項:
Use Resource Injection。該設置決定了是否在 JPA Manager Bean 代碼中使 用資源注入。您將在此處決定,因為您的應用軟件在一個 Web 容器中,而且您正 在使用 Faces Managed Beans。
Use Named Queries。如果該選項能用,在合適的實體中將生成已命名的查詢 ,而且 JPA Manager Bean 查詢方法將使用它們。如果該選擇沒被選中,那麼 JPQL 查詢語句將在 JPA Manager Bean 代碼中直接使用。
Update Entity for use in JSF applications。通過確保實體使用的是,與 JSF 協同工作良好的 Java 類別,該選項能幫助確保 JSF 概述中工作順利進行。
Update Relationship fetch types。設置與所有關系相符的 Eager 或者 Lazy。
您還可以使用該頁面,來為您的應用軟件設置運行時配置細節:
選擇 Configure Project for JDBC Deployment 鏈接以啟動“Set up connections for deployment”條目(圖 18)。
圖 18. 設置運行時聯系細節
在本條目中,您可以建立以下配置文件,JPA 需要使用這些文件,以在運行時 使用合適的聯系信息:
persistence.xml 文件,它包含了聯系的細節信息
orm.xml 文件,它包含了映射信息,以及方案細節
接下來,選擇一個開發時間聯系,它包含了運行時細節。
在聯系區域選擇您的 Derby Sample Connection 。這將在剩余的條目中自動 填充默認值。
您要設置您想在運行時使用的數據源或者資源參考,以及為所有實體使用的默 認方案。如果您要使用單獨的測試和部署方案,那麼您可以在這裡改變默認的方 案。選擇 Deploy JDBC Connection to Server 復選框,將會在您的 EAR 文件的 擴展信息中,自動創建一個數據源。
點擊 OK ,以編輯合適配置文件,並創建數據源。
您不用再去做其他任何事,以讓您的應用軟件在運行時與數據庫聯系起來,這 種操作通常是復雜,且容易出錯的。
完成 Add Manager Bean 向導並觀察生成了什麼產物。Enterprise Explorer 視圖顯示出了所有新生成的實體。
注意它們包含了與數據庫表列,以及設置的主關鍵字、關系相對應的區域(圖 19)。
圖 19. JPA 實體
列表 2 顯示了 Department 實體的 Java 代碼。
列表 2. Department 實體代碼
@Entity
@NamedQueries( {
@NamedQuery(name = "getDepartment",
query = "SELECT d FROM Department d"),
@NamedQuery(name = "getDepartmentByDeptname",
query = "SELECT d FROM Department d WHERE d.deptname = :deptname"),
@NamedQuery (name = "getDepartmentByMgrno",
query = "SELECT d FROM Department d WHERE d.mgrno = :mgrno"),
@NamedQuery (name = "getDepartmentByAdmrdept",
query = "SELECT d FROM Department d WHERE d.admrdept = :admrdept"),
@NamedQuery(name = "getDepartmentByLocation",
query = "SELECT d FROM Department d WHERE d.location = :location"),
@NamedQuery(name = "getDepartmentOrdered",
query = "SELECT d FROM Department d ORDER BY d.deptno"),
@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;
private String mgrno;
private String admrdept;
private String location;
private static final long serialVersionUID = 1L;
@OneToMany (mappedBy="workdept",fetch=FetchType.EAGER)
private List<Employee> employeeList;
// …
// …
類帶上了注釋@Entity,以向 JPA 指示該類是一個被映射的實體。所有已命名 的查詢在實體上被添加了 NamedQuery 注釋。這就使您不管在應用軟件中的任何 地方,都能夠根據它們的查詢名來參考這些查詢,您不必去擔心實際的 Java Persistence Query Language (JPQL)語句。 這種方法讓這些查詢在您的應用 軟件中具有很高的可重用性。如果您想要改變已命名查詢自身的話,它能使您避 免更改所有的參考。
接下來,您可以看到“deptno”已經帶上了@Id注釋,意味著它就是主關鍵字 屬性。Employee 對象的列表被標上了 OneToMany 注釋,以讓 JPA 運行時過程知 道,該區域是由一個關系填充的。
現在讓我們來看看,您的 JPA Manager Beans 是怎樣與實體進行對接的。圖 20 在 Page Data View 視圖下,給您一個關於 JPA Manager Beans 的概述。
圖 20. JPA Manager Beans
您將注意到創建,檢索,更改以及刪除(CRUD)操作,都已被生成 (createDepartment, deleteDepartment, updateDepartment),還有您已經指 定的所有查詢方法,也已生成。Department 實體創建的每一個已命名查詢,都將 會有一個與之相對應的查詢方法。
列表 3 顯示了 DepartmentManager 的 Java 代碼。
列表 3. DepartmentManager 代碼
@JPAManager(targetEntity=entities.Department.class)
@SuppressWarnings("unchecked")
public class DepartmentManager {
@PersistenceUnit
private EntityManagerFactory emf;
@Resource
private UserTransaction utx;
public DepartmentManager() {
}
@Action(Action.ACTION_TYPE.DELETE)
public String deleteDepartment(Department department) throws Exception {
EntityManager em = getEntityManager();
try {
utx.begin();
em.joinTransaction();
department = em.merge(department);
em.remove(department);
utx.commit();
} catch (Exception ex) {
try {
utx.rollback();
} catch (Exception e) {
ex.printStackTrace();
throw e;
}
throw ex;
} finally {
em.close();
}
return "";
}
@Action(Action.ACTION_TYPE.UPDATE)
public String updateDepartment(Department department) throws Exception {
EntityManager em = getEntityManager();
try {
utx.begin();
em.joinTransaction();
department = em.merge(department);
utx.commit();
} catch (Exception ex) {
try {
utx.rollback();
} catch (Exception e) {
ex.printStackTrace();
throw e;
}
throw ex;
} finally {
em.close();
}
return "";
}
@NamedQueryTarget("getDepartmentByLocation")
public List<Department> getDepartmentByLocation(String location) {
EntityManager em = getEntityManager();
List<Department> results = null;
try {
Query query = em.createNamedQuery ("getDepartmentByLocation");
query.setParameter("location", location);
results = (List<Department>) query.getResultList ();
} finally {
em.close();
}
return results;
}
// …
// …
需要注意的第一件事,是將用到資源引入的兩處區域。因為 JPA Manager Bean 被定義為 Faces Managed Bean,所以 Web 容器能夠向代碼引入 EntityManagerFactory 和 UserTransaction ,該代碼如下所示:
@PersistenceUnit
private EntityManagerFactory emf;
@Resource
private UserTransaction utx;
EntityManagerFactory 用於得到一個 EntityManager ,您需要在一個 UserTransaction 中集中所有的處理代碼。
分析 deleteDepartment 方法, 您可以看到該方法接受了一個將從數據庫中 刪除的 Department 實體。該方法首先獲得了一個 EntityManager,然後開始進 行處理。在證實您已經獲得那個實體的最新版本之後,該方法將調用 EntityManager 將它從數據庫中刪除。最終,處理被授權執行,在授權之前,該 操作不會實際運行。
現在讓我們看一下用於檢索部門的查詢方法。方法 getDepartmentByLocation 有一個部門所在地的參數,並返回 Department 實體。該方法得到一個 EntityManager ,然後通過使用在 Department 實體中指定的已命名查詢的名字 ,創建一個 NamedQuery 。其中 NamedQuery 如下所述:
@NamedQuery(name = "getDepartmentByLocation", query = "SELECT
d FROM Department d WHERE d.location = :location")
然後方法設置名為“location”的參數(由 namedQuery 中的 :location 標 示),它使用傳遞給方法的用戶提供的值。訪問 query.getResultList() 實際上 運行了查詢並返回了結果。
現在您已經准備好了您的數據層,您的應用軟件已經可以使用您的實體和 JPA Manager Beans 了。
第二部分. 向 Web 應用軟件添加 JPA 數據
對於本例中的軟件,您想要顯示出一些部門,以及這些部門相對應的員工。另 外,您還想要該軟件具有更新所有員工信息的功能。
您將要創建兩個 Web 頁面:一個顯示出所有的部門,另一個用於更新員工的 信息。
在項目上右擊並選擇 New > Web Page 。創建兩個頁面: listDepartments.jsp 以及 updateEmployee.jsp 。
現在您需要向您的應用軟件添加 JPA 數據。
打開 listDepartments.jsp 文件。
在 Palette 視圖下,有一個 Data and Services 類別,它能讓您向 Web 頁 面添加不同種類的數據(圖 21)。
在選框中選擇 JPA data 項目,並將其拖到頁面上。
圖 21. Data 選框
打開 Add JPA data 向導(圖 22)。在第一頁中,您可以選擇一個可用的, 您想在當前頁面中使用的 JPA Managers。您還可以選擇是顯示單個記錄還是一個 列表,以及是否創建或者更改一個實體。您當前的列表將會顯示出一系列部門。
選擇 DepartmentManager ,然後選擇 Retrieve a list of data 按鈕。
圖 22. Add JPA Data 向導
點擊 Next,這樣您可以在 DepartmentManager bean 中看到所有可用的查詢 方法(圖 23)。
圖 23. 選擇 JPA Query Method
這裡,您將會顯示出各個部門,這些部門是根據它們的部門號進行分類的。
選擇 getDepartmentOrdered 方法。
Query Statement 區域顯示出了,該方法將會采用的實際已命名查詢。
切換到下一頁,您可以選擇您想在 Web 頁面中顯示的列(圖 24)。
圖 24. 選擇在 Web 頁面中顯示的列
考慮到它的目的,您只關心在您的列表中每個部門的簡要概述,例如部門號, 部門名,以及部門員工。
確保列表中只有 deptno ,deptname,以及 employeeList 區域被選中。
employeeList 區域是該部門所有員工的一個列表。 默認條件下,每一個部門 都會被添加一個員工數據表。您可以選擇您想為員工顯示的列。
點擊行右邊的按鈕,以配置 employeeList 控件,然後選擇 empno, firstname,以及 lastname 。
點擊 Finish 以向 Web 頁面添加 JPA 數據。
圖 25 顯示了 Page Designer 的設計視圖下,結果得到的數據表的外觀。
圖 25. 數據表顯示了部門的列表
分析以下 JSP 中生成的源代碼,您會發現,數據表已經與 JSP 的 Page Code 文件中的數據方法捆綁上了(當前頁面的備份 bean):
<hx:dataTableEx id="departmentList1" value="# {pc_ListDepartments.departmentList}"
Page Code 方法包含了檢索部門列表的邏輯(見於列表 4)。方法 getDepartmentList 檢索 DepartmentManager managed bean,然後簡單的訪問了 getDepartmentOrdered()方法,後者是您在向導中選擇的,並將結果返回至頁面 。
列表 4. Page Code 中的 getDepartmentList 方法
@JPA(targetEntityManager = entities.controller.DepartmentManager.class,
targetNamedQuery = "getDepartmentOrdered")
public List<Department> getDepartmentList() {
if (departmentList == null) {
DepartmentManager departmentManager = (DepartmentManager)
getManagedBean("departmentManager");
departmentList = departmentManager.getDepartmentOrdered ();
}
return departmentList;
}
既然現在您已經有了部門的列表,那麼您就可以完成您的第二個頁面,該頁面 能讓您更新一個員工的記錄。
打開 updateEmployee.jsp 頁面。
從 palette 中選擇 JPA Data 項,並將其拖住頁面。
選擇 EmployeeManager 然後選擇操作為 Update an Existing Record(圖 26 )。
圖 26. 添加數據以更新一個 Employee
在向導的下一頁中,出於更新的考慮,您可以選擇怎樣去檢索一個特定的員工 記錄(圖 27)。典型的方法是根據實體的主關鍵字進行查詢,因為這可以保證產 生一個獨一無二的結果。
圖 27. 根據員工的主關鍵字進行檢索
選擇 Get Record By Primary Key 按鈕。
在接下來的頁面中,您要選擇在什麼地方檢索主關鍵字的值(圖 28)。您可 以輸入一個常量或者任意 JSF 表達式。在目前的情況下,您可以使用默認值,這 是一個參數范圍內的變量。
使用 JSF 表達式(param.empno)作為主關鍵字的值。
圖 28. 設置主關鍵字的值
當您 完成 向導上的步驟以後,Web 頁面以及備用的 Page Code 文件將會生 成代碼。圖 29 顯示出了頁面設計視圖的外觀。
圖 29. 顯示以及更新員工記錄的用戶界面
當您點擊 Submit 後,將會生成一個顯示所有員工屬性,並允許更新員工信息 的輸入表格。另外,還會產生一個 Delete 按鈕,該按鈕能允許您去刪除某個特 定的員工信息。讓我們再次查看 Page Code 文件中生成的備份代碼。
一個 getEmployee data 方法會被生成並與 JSF 表格捆綁住(列表 5)。該 方法檢索 EmployeeManager managed bean 並訪問一個方法,以解決 JSF 參數范 圍內傳遞的參數問題。最終,它訪問 EmployeeManager 的 findEmployeByEmpno 方法,傳遞給值 empno ,然後返回檢索後的 Employee 記錄。
列表 5. getEmployee 方法
public Employee getEmployee() {
if (employee == null) {
EmployeeManager employeeManager = (EmployeeManager)
getManagedBean("employeeManager");
String empno = (String) resolveParam("employee_empno",
"#{param.empno}", "java.lang.String");
employee = employeeManager.findEmployeeByEmpno(empno);
}
return employee;
}
方法updateEmployeeAction與deleteEmployeeAction在 EmployeeManager 上 訪問其各自的updateEmployee與deleteEmployee,因此從頁面的當前 Employee 進行傳遞(列表 6)。
列表 6. 更新以及刪除員工信息操作
public String updateEmployeeAction() {
EmployeeManager employeeManager = (EmployeeManager)
getManagedBean("employeeManager");
try {
employeeManager.updateEmployee(employee);
} catch (Exception e) {
logException(e);
}
return "";
}
public String deleteEmployeeAction() {
EmployeeManager employeeManager = (EmployeeManager)
getManagedBean("employeeManager");
try {
employeeManager.deleteEmployee(employee);
} catch (Exception e) {
logException(e);
}
return "";
}
您需要完成的最後一件事,是當您選擇一個員工條目時,建立從您的列表頁面 。到您的更新頁面之間的鏈接。
在頁面 listDepartments.jsp 上,選擇 EmployeeList 數據庫,並在 Properties 視圖下,選擇 Display Options。
點擊“添加一條點擊行時會運行的操作”旁邊的 Add 按鈕(圖 30)。
圖 30. 添加一個行操作
接下來,確保不論何時點擊行時,您都將進入 updateEmployee 頁面:
在 Properties 視圖下點擊 requestRowAction。
點擊 Add Rule 按鈕,以為操作添加一條 JSF 導航規則(圖 31)。
為頁面選擇 updateEmployee.jsp,設置按鈕為“該規則只為這條操作使用” ,然後點擊 OK 。
圖 31. 向 updateEmployee 頁面添加一條導航規則
您還需要向 updateEmployee 頁面傳遞一個參數,以指示顯示哪一個員工。頁 面 updateEmployee 被傳遞給一個名為 empno 的參數。
在 Properties 視圖下,選擇 requestRowAction,然後選擇 Parameter 屬性 (圖 32)。
創建一個名為 empno 的參數,然後將其賦予員工的 empno 值,為選中的行:
#{varemployeeList.empno}
圖 32. 傳遞 empno 作為一個參數
在服務器上運行應用軟件
現在您已經可以在服務器上運行應用軟件。
在 Project Explorer 中右擊 listDepartments.jsp ,然後選擇 Run As > Run on Server 。
在 WebSphere Application Server V7.0 上運行 listDepartments.jsp 頁面 。
部門列表將會顯示出來,V根據部門號進行排序,同時顯示的還有部門中的員 工列表(圖 33)。
圖 33. 在服務器上顯示一系列部門
您可以在任意一個員工條目上點擊,以查看更具體的細節信息。
在第一個員工條目 Christine Haas 上點擊。
您將會前進到 updateEmployee 頁面,在這裡您可以改變員工條目的任意細節 信息(圖 34)。
圖 34. 更新一個員工記錄
也許您想要更改員工的名字:
將名字改為 CHRISTY,姓改為 JOHNSON ,然後點擊 Submit 。
現在返回至 listDepartments 頁面。
更新後的員工信息現在顯示出來(圖 35)。
圖 35. 列表中顯示的更新後的員工信息
總結
您從本篇文章學到,JPA 在您的應用程序中提供了一種數據支持的簡單方式。 除了回顧 JPA 的概念以及優勢,您還可以學到怎樣在一個 Web 頁面中使用 JPA 。本篇文章還引入了 JPA Manager Beans,並解釋了怎樣在 Web 應用軟件中使用 它們,以處理所有的數據支持邏輯。IBM Rational Application Developer V7.5 提供的這些 beans 以及其他工具,能幫助您通過使用 JPA 和 JSF,輕松構建一 個 Web 應用程序。