選擇JDO還是CMP?
由孫賓譯自http://www.onjava.com/pub/a/onjava/2003/05/21/jdo.html
作者:David Jordan 和 Craig Russell
著有《Java Data Objects》一書
2003年5月21日
作者注:JDO和CMP方式的EJB目前正在同時向前發展,但採取的是不同的路線。JDO的核心思想是在企業應用軟件架構的不同層面中存儲傳統的Java對象(Plain Old Java Objects,下稱POJOs),而CMP方案則基於容器環境,並針對特殊的需求。
兩者之間的異同在規範出臺之初便成爲衆所爭論的話題。你可以到JDOCentral.com上看到這類的爭論,而在6月中旬即將在舊金山開幕的2003年JavaOne大會上,也會有一些演示和講解來比較這兩種不同的技術。
在這次JavaOne大會上,3368號技術對話將討論JDO與Struts(一個著名的Web應用架構設計的開源軟件)集成的可行性和實踐經驗;3236號專題研究JDO與EJB容器的結合;1289號專題將對比使用JDO、JDBC和EJB時,設計模式在開發中的應用。
在我們的《Java Data Objects》的第17章有一小段話描述使用JDO和CMP的平衡點。--Craig Russell
JDO還是CMP?
在你對項目開發策略下決定之前,CMP實體Bean和JDO都是值得考慮的方式。
JDO對粗粒度和細粒度的數據對象設計都很適合,具體在一個應用服務器環境中,一般用於SessionBean後面。CMP也是用於SessionBean之後,它的遠程調用很少直接用到。
JDO編寫的類只須編譯一次就可用於分佈式架構中的任何一層,並且在集成到Web或應用服務器之前可以以單層或兩層的方式先調試好。而CMP只能在發佈到一個具體的應用服務器後才能調試。
JDO沒有直接定義遠程行爲,這一點與Servlet、JSP和EJB組件不同。所有的分佈處理、事務和安全方面的策略都基於獨立存儲管理器,該管理器負責處理你的對象模型中所有的類實例。這一點也說明你可以在分佈式環境中的任何層面上使用JDO,而其遠程行爲由容器來實現,而不是JDO廠商。
CMP組件提供了較高的可移植性,Bean類及其描述符都是規範化的。多數的不兼容性只存在於規範所未能盡述的地方,包括如何將類映射到具體的數據庫(不限於關係數據庫)、類似只讀類的可選功能、其它方面的廠商擴展。而JDO產品視具體廠商所支持的可選功能而有所不同。
CMP中,對象之間的關係是受控的,即一端的改變會影響到另一端,並且對應用是可見的。而JDO不支持關係的管理,只是一些廠商以擴展的方式提供類似功能。
繼承是對真實對象建模時常用的概念,但CMP並不支持它。CMP在組件的定義和實現時並不一致,在具體實現一個EntityBean接口時,實現的類可以具有繼承關係,但在定義這個EntityBean時卻不行。類之間的關係也只是在接口之間,而不是在實現類之間,因此這些關係也不存在多態性。舉例來說,一個名爲MediaItem的CMP Bean類不能直接聯繫到名爲MediaContent的類,因爲MediaContent是抽象的,類並無具體實例。要建立這樣的聯繫,你只能將其轉換爲兩個關係:一個是MediaItem與Movie類,一個是ModiaItem與Game類,並且在每個相關方法中,你必須針對兩個關係區別對待。
在訪問對象屬性上,CMP和JDO也天差地別。CMP Bean中,所有的屬性和對象關係都是作爲抽象的get和set方法定義在描述符中,對實際屬性的訪問只能由具體的由相關工具生成的實現類去完成。而JDO中,可保存的屬性和關係在描述符中聲明,並且在代碼中也可以直接訪問這些屬性,包括JDO產品生成的代碼在內。JDO增強器會在增強時適當地改造這些代碼。
JDOQL和EJBQL都提供了類似的查詢數據的方法。兩者都可以在程序中查詢並訪問數據對象,都採取“讀-改-寫”的策略,都不是完整的數據操縱語言(比如沒有數據更新語句),它們都只用於查找數據對象並在代碼中訪問。
CMP要求所有的訪問操作都在事務環境中,非事務方式的訪問不受支持。而JDO允許你決定是否採用事務方式。對需要更新數據的地方,JDO要求採用事務,而只是讀取的代碼中,包括緩衝在內,JDO支持非事務方式的訪問。
表17-1是對CMP Bean和JDO可存儲類的比較
表17-1 CMP beans與JDO的比較
特性 | CMP beans | JDO可存儲類 |
---|---|---|
環境方面 | ||
應用可移植性 | 基本可以,很少有負面影響 | 規範定義的原則下可移植 |
應用環境 | 應用服務器 | 單層、兩層、Web服務器、應用服務器 |
可存儲類相對於環境的獨立性 | 低:類必須實現EJB接口,並在EJB容器中執行 | 高:類不需要實現任何特定接口,可在任何環境中執行 |
元數據(metadata) | ||
標記可存儲類 | 發佈描述符標明所有的可存儲類 | 元數據標明所有可存儲類 |
標記可存儲屬性 | 發佈描述符標記所有的可存儲屬性和關係 | 元數據中默認大部分可存儲屬性和關係(簡潔) |
建模 | ||
域類的建模對象 | CMP bean (抽象的底層數據庫) | 可存儲類 |
域類間的繼承 | 不支持 | 完全支持 |
屬性訪問 | 抽象的get/set方法 | 任何方式的訪問,包括直接訪問和get/set方法 |
Collection, Set | 支持 | 支持 |
List, Array, Map | 不支持 | 可選功能 |
關係 | 體現爲對CMP本地接口的引用 | 體現爲對JDO可存儲類或接口的引用 |
多態性 | 不支持 | 支持 |
編程 | ||
查詢語言 | 類似SQL的EJBQL | 基於Java布爾判斷的JDOQL |
遠程方法調用 | 支持 | 不支持 |
生命週期管理對類方法的要求 |
setEntityContext |
無參構造器(可以是private的) |
可選的回調方法 | ejbCreate ejbPostCreate ejbFind |
jdoPostLoad jdoPreStore jdoPreClear jdoPreDelete |
關係數據庫映射 | 廠商相關 | 廠商相關 |
方法安全策略 | 支持 | 不支持 |
方法的事務策略 | 支持 | 不支持 |
非事務訪問 | 非標準 | 支持 |
需要的類/接口 |
EJBLocalHome,本地接口(如果支持本地訪問) EJBHome,遠程接口(如果支持遠程訪問) 抽象類必須實現EntityBean 標識類(如果不是原始類型) |
可存儲類 標識類(只用於自定義標識) |
事務同步回調 | 不支持 | 支持 |
David Jordan創立了Object Identity, Inc.,提供Java Data Objects(JDO)的諮詢和培訓服務。David也是《Java Data Objects》一書的作者之一,另一作者是Craig Russell。
Craig Russell是Sun微系統公司的JDO規範領導者。
O'Reilly及其協會最近(2003年4月)出版了《Java Data Objects》。
。本文的版權屬於筆者本人,但歡迎轉載,前提是註明出處和原作者。另外,歡迎在我的專欄中查看我的另幾篇文章,並提出寶貴意見!