日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

使用 EJB 3.0 Java Persistence API 設(shè)計企業(yè)應(yīng)

系統(tǒng) 2378 0
本文將介紹 Java? Platform, Enterprise Edition (Java EE 5) 的一種設(shè)計方法,它利用了 Enterprise JavaBeans? (EJB) 3.0 新的 Java Persistence API (JPA)。JPA 提供了一種標(biāo)準(zhǔn)的對象關(guān)系映射解決方案,該解決方案避免了依賴第三方框架(如 Hibernate)。您將看到示例應(yīng)用程序的詳細內(nèi)容,其中驗證了本方法并闡明關(guān)鍵設(shè)計決定。
<!--START RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --> <!--END RESERVED FOR FUTURE USE INCLUDE FILES-->

期待已久的下一版本 Java EE 5 即將發(fā)布(參見 參考資料 獲得規(guī)范和預(yù)覽版的鏈接)。Java EE 5 許多新功能都包含經(jīng)過修補的 EJB 架構(gòu),其突出特性之一是 JPA。由于具有容器內(nèi)和容器外持久性選項,JPA 為 J2EE 架構(gòu)師帶來一系列全新設(shè)計選擇。本文將著重介紹容器內(nèi)應(yīng)用程序的設(shè)計,此類應(yīng)用程序依賴 EJB 容器提供企業(yè)服務(wù),如事務(wù)處理和安全性。

我將使用您熟悉的 PetStore 應(yīng)用程序進行測試,以證明 JPA 的功能以及它如何向傳統(tǒng) J2EE 設(shè)計模式發(fā)起挑戰(zhàn)。本應(yīng)用程序比較瑣碎,所以不提供詳盡的實現(xiàn)細節(jié)。我將用代碼摘錄對設(shè)計注意事項進行說明(完整開放源碼的連接請參見 下載 )。本文假設(shè)您熟悉 EJB 3.0 基本概念和對象關(guān)系(OR)映射基本概念。(若需了解這兩個主題的更多信息,請參閱 參考資料 )。

設(shè)計概述

示例 PetStore 應(yīng)用程序是基于 Web 的電子交易應(yīng)用程序,它實現(xiàn)以下用例:

  • 瀏覽產(chǎn)品
  • 查找產(chǎn)品
  • 維護賬戶
  • 維護購物車
  • 創(chuàng)建訂單

本應(yīng)用程序被設(shè)計為具有三個主要邏輯層的多層 Java EE 應(yīng)用程序:

  • 表示層 (并非本文的重點)使用 Struts 框架。

  • 服務(wù)層 是一種簡單的服務(wù) facade,將所有工作委托給其協(xié)作者。服務(wù)層的目的是分離服務(wù)供應(yīng)與服務(wù)實現(xiàn)。

  • 數(shù)據(jù)訪問層 是一系列作為無狀態(tài)會話 bean 實現(xiàn)的粗粒度 Data Access Objects (DAO)(參見 參考資料 )。出于持久性的需要,它們都依賴 Java 持久性實體管理器。

應(yīng)用程序域模型由 EJB 3.0 實體 bean 表示并用于層間的通信。當(dāng)域?qū)ο箅x開數(shù)據(jù)訪問層時,它與實體管理器脫離。當(dāng)重新進入數(shù)據(jù)訪問層時,它需要重新連接到實體管理器。

注釋似乎是 Java 5 的一個廣泛采用的特性,JPA 也不例外。注釋可用于指定 OR 映射 —— 在 dW 文檔和教程中您經(jīng)常可以看到 —— 而 PetStore 應(yīng)用程序出于相同目的使用它們。然而值得一提的是您還能通過映射文件的方式指定 OR 映射。本文稍后的 OR 映射 一節(jié)將探討并比較這兩種可選方式。

我在 Jboss 應(yīng)用服務(wù)器中開發(fā)并部署 PetStore 應(yīng)用程序(參見 參考資料 )。我使用商用數(shù)據(jù)庫完成大多數(shù)開發(fā)工作并將應(yīng)用程序后端移植到 PostgreSQL 數(shù)據(jù)庫( OR 映射 一節(jié)包含了關(guān)于使用 JPA 時您應(yīng)該了解的數(shù)據(jù)庫遷移的潛在影響的討論)。

本案例分析的目的之一是符合設(shè)計標(biāo)準(zhǔn),允許高度可測試的實現(xiàn)。如 測試 一節(jié)所見,您能夠使用一系列測試技術(shù)來測試 PetStore 應(yīng)用程序。

PetStore 應(yīng)用程序充分利用了這一事實:它是規(guī)則的 Web 應(yīng)用程序。主要優(yōu)點是所有層能夠運行在相同的 JVM 中,免除了組件分發(fā)的需要。本文的 遠程處理 一節(jié)簡要介紹了為應(yīng)用程序添加遠程處理功能的方法。




服務(wù)層

服務(wù)層被設(shè)計為服務(wù) facade。它由 PetStoreService 這一無狀態(tài)會話 bean 實現(xiàn)。Bean 要完全依靠其協(xié)作者來提供 Web 服務(wù)。

因為簡化的 PetStore 要求被限定于從數(shù)據(jù)庫檢索數(shù)據(jù)并把數(shù)據(jù)存儲于數(shù)據(jù)庫,惟一的協(xié)作者就是 DAO。真正的應(yīng)用程序能夠調(diào)用 Web 服務(wù),通過 RMI/IIOP 或資源適配器訪問其他應(yīng)用程序,并生成電子郵件消息等。所有此類型的功能都需要其他協(xié)作者支持。

可通過 @EJB @Resource 注釋注入?yún)f(xié)作者(如清單 1 所示)或通過 @PostConstruct 方法注入?yún)f(xié)作者(如清單 2 所示):


清單 1. 使用 @EJB 注入?yún)f(xié)作者
            @EJB(beanName = "AccountDao")
            
AccountDao accountDao;


清單 2. 使用 @PostConstruct 注入?yún)f(xié)作者
            MessageSource messageSource;
            
@PostConstruct
public void init() {
messageSource = new MessageSourceImpl("exceptions");
}

選擇 bean 實現(xiàn)類的測試策略的主要因素是類完全依賴協(xié)作者來提供服務(wù)。這意味著類和協(xié)作者的交互作用需要被驗證。正如您在 測試 一節(jié)看到的,模仿對象方法完全滿足該目標(biāo)。


數(shù)據(jù)訪問層

數(shù)據(jù)訪問層被設(shè)計為一系列粗粒度的 DAO。DAO 被實現(xiàn)為無狀態(tài)會話 bean,一個 bean 對應(yīng)一個邏輯域: AccountDao OrderDao ProductDao

每個 bean 都要把實體管理器注入到其中:

            @PersistenceContext(unitName = "manager1")
            
protected EntityManager em;

這是應(yīng)用程序中 持久性調(diào)用類(persistence-aware) 最多的層。它廣泛使用全新的 Enterprise JavaBeans Query Language(EJB QL)(參見 參考資料 )。所有持久性相關(guān)的行動都在該層發(fā)生,例如:

            profile = (UserProfile) em.createQuery(
            
"from UserProfile up where up.login = :login").setParameter(
"login", login).getSingleResult();

下面是另一個例子:

            em.persist(account);
            

事實上這些類是持久性調(diào)用類(persistence-aware),需要一種容器內(nèi)測試策略,這將在 測試 一節(jié)進行描述。


域模型

您可以把 JPA 看作是眾所周知的透明持久性技術(shù)(如 JDO 和 Hibernate)的繼承者。盡管透明持久性可看作一個附加(add-on)服務(wù),可被應(yīng)用到忽略持久性的 Plain Old Java Objects (POJO)中,但 JPA 還是對域?qū)ο笫┘恿松倭肯拗啤?

首先,您通常要具有一個映射到對應(yīng)數(shù)據(jù)庫表主鍵的(代理)對象標(biāo)識符:

            @Id
            
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "AccountSeq")
@Column(name = "account_sysid")
public Integer getAccountId() {
return this.accountId;
}

其次,在聯(lián)機事務(wù)過程(OLTP)環(huán)境中,需要一個 version 字段或 JavaBean 屬性以進行樂觀并發(fā)控制:

            @Column(name = "row_version")
            
@Version
public int getVersion() {
return version;
}

最終,如果您選擇使用注釋方式的映射,映射注釋將分布在代碼周圍。

另一種限制源自于這樣一個事實:域?qū)ο罂梢酝ㄟ^由實體管理器所管理的域?qū)ο笏诘膶釉L問,也可以通過分離它的所有其他層訪問。此外,對象可能是新的或已刪除的。一般情況下,對象的行為取決于其持久性狀態(tài)。例如,假設(shè)在實體管理器中執(zhí)行以下這行代碼:

            int size = attachedProduct.getItems().size();
            

項集合使用給定產(chǎn)品的項填充, size 變量的值大于 0。如果使用默認懶加載(lazy)配置的一對多關(guān)聯(lián),并在表示層中執(zhí)行同一行代碼, size 變量的值為 0。 換句話說,在實體管理器之外(在實體管理器內(nèi)也沒關(guān)系)無法把 非活動(lazy) 對象與 活動(eager) 對象區(qū)分開。解決此問題的方法是強制執(zhí)行項目規(guī)范和約定。

在域?qū)ο笾校梢园严嗤耐评響?yīng)用到業(yè)務(wù)方法。無論是否在實體管理器中,它們都應(yīng)該準(zhǔn)備好在任何層中調(diào)用。這就是把域?qū)ο笾械臉I(yè)務(wù)方法數(shù)量限制為必要的最少數(shù)量的理由。

雖然有上述各種情況,域?qū)ο笠廊槐A粼S多 POJO 特性。這意味著您可以使用 plain old Java test (POJT) 對業(yè)務(wù)方法進行測試,POJT 這一術(shù)語引自 Expert One-on-One J2EE Development without EJB 一書(參見 參考資料 。)



OR 映射

OR 映射是圍繞 JPA 設(shè)計的應(yīng)用程序的重要元素。它直接影響實體管理器填充域?qū)ο蟮姆绞健R虼耍兏成淠軌蛟诒硎緦佑X察到。變更獲取類型或級聯(lián)類型可能將產(chǎn)生非常不利的影響。

正如前面所述,有兩種定義映射的方法:元數(shù)據(jù)(注釋)和映射文件。盡管我們高度提倡采用元數(shù)據(jù)的方法,但您應(yīng)該也注意到了它所帶來的不便。從本質(zhì)上 講,此方法牽涉應(yīng)用程序的兩個邏輯層:域模型和映射信息。因為這兩個層是分散的,所以這兩個層需要使用不同技術(shù)進行單獨測試。元數(shù)據(jù)方法本身不會影響層的 可測試性。更確切的說,元數(shù)據(jù)方法使這兩個層好像只是一個層,由于受一系列因素的影響,這可能會引起問題。

影響映射方法選擇的一個因素是項目小組結(jié)構(gòu)。在只有少數(shù)開發(fā)人員參與的小型項目中,表的數(shù)量很少(一般說來少于 100 個表)而且沒有專職的映射人員,因為通常使用注釋會更加快速,所以把注釋方法看作定義映射也許是最佳選擇。對于擁有專職映射人員或映射小組的中型和大型項 目來講,使用映射文件的方法才是更好的選擇。該方法可以降低資源爭用并使開發(fā)過程具有另一種自由度。基于元數(shù)據(jù)的映射方法證實是 PetStore 應(yīng)用程序更加節(jié)省時間的方法。

OR 映射層的目的是使其余應(yīng)用程序免受底層數(shù)據(jù)庫變更的影響。當(dāng)把 PetStore 應(yīng)用程序后端遷移到 PostgreSQL 時,無需對映射層作出任何變更。這可能要歸結(jié)于這一事實:原始數(shù)據(jù)庫和 PostgreSQL 這兩者均支持序列,因此主鍵生成策略保持完好。一般情況下,您應(yīng)該對與對象 ID 處理相關(guān)的映射區(qū)域進行重寫。

對映射的全面測試覆蓋極為重要。必須覆蓋所有關(guān)系映射以確保對獲取行為和過渡持久性進行測試。您能夠利用容器外使用的 JPA 來執(zhí)行該任務(wù)(將在下一節(jié)進行詳細介紹)。



測試

服務(wù)層設(shè)計的關(guān)鍵要素是,關(guān)注與底層的協(xié)作以提供請求的服務(wù)。這需要考慮到使用動態(tài)模仿對象的可靠測試策略。我使用 EasyMock 框架(參見 參考資料 )來實現(xiàn)測試方法。

DAO 層具有強大的數(shù)據(jù)庫內(nèi)聚力。這就是可靠測試需要某類容器內(nèi)策略和數(shù)據(jù)庫訪問的原因。盡管這對于遠程 EJB 很容易,還是需要考慮適合本地 bean 的有意義的方法。此處令人困擾的因素是:

  • 需要容器內(nèi)測試 facade
  • 域?qū)ο笫欠沁B續(xù)的,所以全部驗證需要發(fā)生在容器內(nèi)。

JBoss Embeddable EJB3 容器(參見 參考資料 ) (撰寫這篇文章時尚處于測試版階段)被證實是更適當(dāng)?shù)倪x擇。因為能夠從單元測試啟動 JBoss Embeddable EJB3 容器,這樣所有代碼都運行在同一 JVM 中。使用可嵌入容器的容器內(nèi)測試可實現(xiàn)它的目標(biāo),但過程比較緩慢,因為容器啟動時間就需要大概 30 秒。這種問題可能是由較早的產(chǎn)品狀態(tài)造成的,可通過合理的配置改進。

我采用 POJT 對域模型類的業(yè)務(wù)方法進行測試。不需要其他測試技術(shù),況且其他測試技術(shù)不適合這些類。

OR 映射是一個需要窮舉測試覆蓋的主要層。該層對數(shù)據(jù)庫非常敏感,所以該層不能應(yīng)用模仿對象或 POJT 技術(shù)。但是,您可以利用 JPA 的容器外功能。我就使用這種策略來測試 PetStore 或 OR 映射層。

您需要牢記測試中的測試關(guān)聯(lián)和過渡持久性行為的重要性。這樣您才能及早注意到獲取類型的變更或級聯(lián)類型值的變更,并采取適當(dāng)?shù)拇胧?


遠程處理

PetStore 應(yīng)用程序設(shè)計的關(guān)鍵特性是它的本地特性。使應(yīng)用程序的所有邏輯層運行在同一 JVM 中,這種方法具有很多優(yōu)點。有關(guān)該主題的詳細討論,請參閱 Expert One-on-One J2EE Development without EJB (參見 參考資料 )。

不過,應(yīng)當(dāng)說明的是:通過 遠程處理 facade ,您可以輕松向應(yīng)用程序添加遠程處理功能。遠程處理 facade(而不是我在前面描述的服務(wù) facade)公開了一個遠程界面,它具有兩個職責(zé):進行域模型和順序數(shù)據(jù)傳輸對象(DTO)(參見 參考資料 )之間的相互轉(zhuǎn)換和在服務(wù) facade 上調(diào)用適當(dāng)?shù)姆椒ā?

使用遠程無狀態(tài)會話 bean 能夠?qū)崿F(xiàn)本應(yīng)用程序。唯一障礙是創(chuàng)建其他 DTO 層和進行它們與域模型之間相互轉(zhuǎn)換。然而您需要它來確保實現(xiàn)整潔的界面以及與遠程客戶機的松散耦合。


結(jié)束語

EJB 3.0 和 JPA 毫無疑問將是 Java EE 5 的主要賣點。在某些領(lǐng)域中,它們給正常的 Java 社區(qū)帶來競爭優(yōu)勢,并使 Java 在其他領(lǐng)域與競爭對手不分伯仲。(不可否認的是,目前某些領(lǐng)域尚不存在基于標(biāo)準(zhǔn)的方法。)

過去數(shù)年來,Spring Framework(參見 參考資料 )一直是 EJB 在企業(yè)領(lǐng)域的主要競爭對手。EJB 3.0 規(guī)范解決了很多促進 Spring 興起的問題。隨著它的出現(xiàn),EJB 3.0 毫無疑問比 Spring 提供了更好的開發(fā)體驗 -- 最引人注目的優(yōu)勢是它不需要配置文件。

JPA 提供一種標(biāo)準(zhǔn)的 OR 映射解決方案,該解決方案完全集成到 EJB 3.0 兼容的容器中。JPA 的前輩將會繼續(xù)穩(wěn)定發(fā)展,但是業(yè)務(wù)應(yīng)用程序中的 raw 使用將可能會減少。實現(xiàn) JPA 兼容的實體管理器似乎很可能是此類技術(shù)的發(fā)展方向。

在撰寫本文時,EJB 3.0 規(guī)范還處在建議的最終草案(Proposed Final Draft)階段(參見 參考資料 )。以下是一些未解決的問題以及與 JPA 相關(guān)的預(yù)實現(xiàn):

  • ? 當(dāng)前形式的 JPA 規(guī)范沒有定義只讀實體 bean。這讓人困惑,因為兼容 EJB 2.1 規(guī)范的實體 bean 支持這種特性。Spring 框架也支持只讀事務(wù)。

  • ? 可插入的持久性提供者概念仍處于未交付的階段。

  • ? 標(biāo)準(zhǔn)樂觀并發(fā)異常 -- OptimisticLockException -- 首次出現(xiàn)在 EJB 3.0 Proposed Final Draft 中。在持久性提供者執(zhí)行它以前 ,您還需要使用特定于提供者的異常,如 Hibernate 的 StaleObjectStateException,來檢測樂觀并發(fā)問題。暫時,這種情況限制您的實現(xiàn)只能采用特定的持久性提供者。

Java EE 系列規(guī)范的較大問題與 JPA 沒有任何關(guān)系。Java EE 系列規(guī)范的問題涉及到 Web 和 EJB 容器之間的集成。Spring 在此領(lǐng)域仍然具有主要競爭優(yōu)勢。JBoss 的 Seam 項目(參見 參考資料 )嘗試使用自定義的方法來解決這一問題。Caucho Resin 應(yīng)用服務(wù)器(參見 參考資料 )試圖擴展容器邊界并支持在 Web 容器中使用 @EJB 注釋。我們希望 Java EE 5.1 將解決層集成的問題,為我們提供一個全面而標(biāo)準(zhǔn)的依賴性注入方法。



下載

描述 名字 大小 下載方法 PetStore
j-ejb3jpapetstore.zip 149KB HTTP
關(guān)于下載方法的信息


參考資料

學(xué)習(xí)

獲得產(chǎn)品和技術(shù)


關(guān)于作者

Borys Burnayev 是一名具有超過 12 年從業(yè)經(jīng)驗的軟件開發(fā)人員,過去 5 年中,他從事 Java 及相關(guān)技術(shù)的工作,最近開始專注于 J2EE 設(shè)計問題與對象關(guān)系技術(shù)。Borys 擁有應(yīng)用數(shù)學(xué)的碩士學(xué)位。他還擁有 Sun Certified Architect 技術(shù)認證和 Sun、Oracle 、IBM 多家公司的其他技術(shù)認證。

使用 EJB 3.0 Java Persistence API 設(shè)計企業(yè)應(yīng)用程序


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 万载县| 昌邑市| 嘉黎县| 香港 | 靖江市| 汶上县| 新竹县| 大丰市| 光山县| 息烽县| 房产| 亚东县| 台江县| 成武县| 秭归县| 沛县| 改则县| 山东省| 诸暨市| 阿合奇县| 嘉峪关市| 璧山县| 双城市| 寻甸| 怀远县| 东乡族自治县| 平江县| 阜新| 汽车| 厦门市| 宝坻区| 宁波市| 邵东县| 隆林| 敦化市| 即墨市| 怀远县| 黔南| 盐边县| 漳浦县| 博湖县|