Entity Bean vs Hibernate Pojo

 

該文轉自guty

O-R Mapping

J2EE的標準是CMP Entity Bean,而實際應用中受到詬病最多的也是它。我們化了整整半年時間研究CMP2.0的開發方法,目前總算能夠將代碼量減少到70%,並且有希望減少到 90%。我曾經很滿足現有的成績,但是當我真正地閱讀了hibernate後,對CMP2.0的信心徹底動搖了。

hibernate至少比CMP2.0有以下優點:
1. 兼容性。 規範一模一樣,實現各有不同,這是CMP的現狀。用第三方O-R Mapping工具可以解決這個問題。
2. 保護智力投資。在瞭解了Orion, Weblogic, JBoss的CMP實現後,我不願意再去學習Websphere 或者Resin的實現了。
3. 性能。
a. local v.s. remote, hibernate、JDO、Castor都是本地調用,CMP2.0雖然也有Local接口,但是Web層還是需要通過Remote接口訪問EJB層的數據,序列化、網絡調用、創建大量的對象,都是性能降低的原因。
b. transaction,J2EE提出了一個全新的事務模型(method-based descriptor),對程序員的開發確實是個“簡化”,記得一本教程建議所有的EJB方法都用Required。但這樣的結果是什麼?性能極度降低!互鎖!沒有辦法,我們只有再去調節各個方法的Transaction屬性,然後又出現 新的互鎖...
新的事務模型是不成功的。它試圖簡化問題,卻引入了更爲嚴重的問題。各家廠商的Transaction實現也不盡相同,有的支持Optimistic Lock,有的在VM中同步Entity對象,又是兼容性的一大敵。
hibernate沒有試圖創造一個更新的模式,相反,它沿用了傳統數據庫的Transaction編程模式,在對J2EE的Transaction傷透腦筋後看到它,真是十分親切,感覺自己確實在編程,而不是碰運氣填代碼了。
4. 動態Query。
Entity Bean很難實現動態Query,這是因爲它基於代碼自動生成技術,即最終的執行代碼是在部署編譯時生成的。hibernate則有根本的改變,它基於 reflection機制,運行時動態Query是很自然的事。另外,hibernate幾乎支持所有的SQL語法,傳統數據庫可以做的它就可以做。
5. 發展速度。
I have a dream, 有一天Entity Bean會變得很好。但至少目前來看,Entity Bean是一個不完善的產品,它是大公司政治鬥爭和妥協的產品,而且習慣性將一些問題“無限期擱置”,典型的例子就是Query(之所以不提其他問題,是因爲其他都是Entity Bean的致命傷:))
形成強烈反差的是,hibernate的核心程序員只有一人,但它改進的速度確是Entity Bean無法企及的。
6. 繼承和多態。
OO語言的精華在Entity Bean這裏是行不通的,我曾經自我安慰將Entity Bean看做一個“內存中的數據表”,才找到了一點平衡。
但當我看到hibernate時,又開始不平衡了。

另外,CMP2.0也有一些缺點是可以彌補的。
1. 代碼維護。
大量的接口文件和配置文件,開發和維護的工作量很大。
解決途徑:採用xdoclet,可以自動產生衆多的接口和配置文件,甚至facade, delegate等高級模式。

至少目前來看,hibernate的缺點有:
1. 代碼維護
hibernate提供了自動生成mapping文件“框架”的工具,但還需要手工調節。而這類開發,能想到的最佳模式就是xdoclet的(代碼+註釋)的模式了。幸好,hibernate的程序員已經向xdoclet項目增加了hibernate的模塊。現在需要的是等待xdoclet的下一個 release。

結論:
hibernate至少從文檔上超越了Entity Bean很多,我要學習hibernate。

以下是robbin的觀點

如果說不使用Session Facade模式的話,我認爲EB還是一個很有意義的的東西,因爲EB是唯一直接支持跨RMI的持久化方案。但是由於EB的效率和減少跨RMI的網絡調用的原因,EB已經完全被封裝到SB的後面,EB的分佈式調用的功能,EB的安全驗證功能,EB的容器事務功能完全被前面的SB給做了,結果EB就只剩下了唯一的ORM功能了,單就ORM這一點來說EB實在是一個非常非常糟糕的東西。那麼EB還有什麼功能值得我非去用它不可呢?

用 Session Bean + DAO + Hibernate 來取代 Session Bean + Entity Bean,不但能夠極大降低軟件設計難度,軟件開發難度,軟件調試難度和軟件部署難度,而且還可以提高允許效率,降低硬件要求。

不要把EB直接拿來和Hibernate做比較,兩者不是一個範疇的東西,而應該整體比較兩種方案:
Session Bean + DAO + Hibernate
Session Bean + Entity Bean
我找不出來第二方案有哪怕一點方面能夠比第一方案好的。

CMP可以使用CMR來表示多表之間通過外鍵關聯的關係。但是你仍然會遇到即使沒有鍵關聯的表仍然需要連接查詢的情況,這是一個非常普遍的現象。

如果是Hibernate,可以在HSQL裏面定義outer join,BMP也可以寫JDBC,而CMP沒有任何辦法來解決該問題,除非你把需要的連接查詢都定義爲CMR,但那樣的話,凡是有需要連接查詢,或者有鍵關聯的表都必須打在一個包裏面。你如果不打在一個jar包裏面,如果能夠建立CMR?不是我想放在一個jar裏面,而是不得不放在一個jar裏面。基本上CMP還是非常笨拙的。

CMP的另一大缺點是不能動態SQL,guty已經提到了,一個SQL就要定義一個EJBFinder方法,在編譯的時候就確定死了。在實際應用中,經常會遇到不確定查詢條件的查詢,比如說用戶在頁面上用下拉列表來選擇查詢的條件,用戶既有可能什麼限制條件都不選,也有可能選擇某幾個條件。這時候你怎麼辦?假設有n個查詢條件,你要寫 C1n + C2n + C3n +...+ Cnn(C是組合公式的符合,n是下標,1...n是上標)個EJBFinder方法才行,很恐怖吧。

其實JDBC的PrepareStatement也不能很好的解決這個問題,因爲它是按照1,2這樣的次序來set參數的。用Statement是肯定不行的,會嚴重影響數據庫,甚至會導致數據庫down掉(我的實際經驗)。但是Hibernate就解決的不錯,因爲它可以按照 :name 這樣的形式來設定SQL中的Placeholder,這樣set參數就可以按照參數名稱傳遞,因爲次序不是死的,在程序裏面就很容易根據用戶選擇的查詢條件,動態的產生SQL,動態的set參數了。

CMP2.0還有一個大問題是不支持order by,當然你可以在Java裏面對取出來的集合排序,但是速度和數據庫裏面就排好序速度不在一個數量級了。Hibernate不但可以order by,還可以group by,having,子查詢,真是沒有辦法比下去了。

其實對於動態SQL和排序問題,特定的App Server也可以做,但那不是CMP2.0的規範罷了,所以爲了可移植性,也不敢隨便去用。

在項目開發時, 開發和運行效率以及靈活性是非常重要的指標。由於Entity Bean天生是一種粗粒度的使用方式,這就必定使它在裝載的時候有較長的響應時間,也不能自如的支持懶裝入的方式,使用成細粒度會使程序變得複雜,以及遠程調用細粒度的entity bean是一種非常可怕的行爲, 太慢了.

Hibernate正好滿足開發和運行效率以及靈活性,說來說去,它可以稱做一個OO化的JDBC, 這樣大家就不會對Hibernate產生誤解及恐懼心理。它支持粗細兩種粒度方式,運用起來靈活自如,前提是你必知道如何使用,一個entity bean 實現要N種重複的方法, such as ejbRemove,ejbstore,ejb...., 光類也有一大堆,象Home Interface, Romote Interface..., Primary class if necessary. Hibernate只需要一個就行了。

CMP在進行O/R Mapping方面只是做了最基礎的工作而已,完全用CMP做數據層,會發現你在把數據庫應該做的工作全部都搬到App Server裏面來重新實現一遍,有這必要嗎?

CMP是把EJBQL寫死在ejb-jar.xml裏面的,所以n個條件就需要(c0n+c1n+...cnn )2的n次方個EJBFinder方法,簡直沒有辦法說。

JDBC實現PrepareStatement的動態SQL構造不是不能夠,而是非常麻煩,需要寫一個非常非常大的if elseif else嵌套的判斷。

Hibernate實現起來特別簡單,(其實OJB也實現了PrepareStatement的動態SQL構造)這本身並不複雜,但是需要你多寫些代碼而已,由於CMP把EJBQL寫死在配置文件裏面了,你連選擇的餘地都沒有。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章