2010-01-19 18 views
8

當您從多個數據源中提取模型對象時,最佳方法是什麼?模型/實體類是否存在模式

例如我有一個應用程序有一些數據存儲在mySQL數據庫中使用休眠。如果我想在EC2或Google App Engine中存儲其他一些對象?我知道DAO抽象了與特定數據源一起工作的實現,但實體本身又如何?

起初我認爲使用jpa註釋註釋我的實體是一個很好的解決方案,但現在看來我真的把我的實體綁定到特定的實現。以App Engine爲例,其中一些註釋是沒有意義的。

看來我需要一個純粹的POJO類來表示我的實體,完全沒有持久性邏輯。例如,如果我想模擬一隻狗,(是的,跛腳的選擇,但無論如何)。
會是有意義的有一個抽象的狗類,然後定義子類特別持久化解決方案的工作:HibernateDog,GAEDog等

感謝。

回答

4

這是一個很好的問題,即使問題不是新的。作爲一個行業,這些年來我們經常改變這個問題的「傳統觀點」。你今天得到的答案不一定是5年前或5年後的結果。

想象如何我想喜歡處理這個項目,我想知道一些你還沒有說明的事情:你的應用程序是狗實體的「記錄系統」嗎?還有哪些子系統/層/應用程序需要了解有關Dog實體的信息。在Java中,當您編寫像Animal> Dog這樣的全新類型時,您將獲得以下獎勵:有機會編寫更多知道如何與Animal對象和Dog對象進行交互的代碼。我在2010年不太確信這是一個比五年前更好的主意。

您是否負責設計存儲狗信息的數據庫?我們以前一直都這樣做,但現在我通常會發現自己與其他系統實際管理的數據記錄集成在一起:Google API,LDAP實體,數據倉庫,Peopleoft等產品。

如果您而不是負責定義什麼是狗,以及它們如何與宇宙互動,我會看看一個領域不可知的方式來模擬狗的信息在記憶中。有噸:XML/DOM,JSON,地圖等

在這些格式中移動其他人的數據有很多優點......

  • 你沒有寫的POJO
  • 這些豐富的功能,文檔和測試
  • 有許多現有的API進行改造,操縱和序列化這些生物
  • 你可能會得到跨其他領域重用你的視圖/控制器/其它代碼

另一方面...如果您是Dog數據的記錄系統,請考慮使用接口而不是抽象類。或者也許接口抽象類。 Java只有單一的繼承;將您的視圖/控制器/其他代碼綁定到接口以保證最大的未來靈活性。

2

Hibernate的一個問題是它將自己的Collection實現注入到您的域類中,如果您嘗試使用序列化(例如從服務器到客戶端)通過線路發送您的類,則會導致問題。

在你上面的例子中我會質疑需要提供存儲特定的子類:

DO /如若真的類包含關於它們被存儲的方式狀態?這是否是這個概念的核心,因此值得在繼承時使用「一槍」(用Java來說)?我認爲,在你的例子更有用的繼承層次會是這樣的:

  • 動物
    • 哺乳動物

此外,如果您希望將實例保存到Hibernate,但不知道Dog是否爲HibernateDog,GAEDog等,並且必須執行檢查/向下轉換在此刻。

1

你似乎是正確的方法。良好的設計並不意味着實體不受技術的束縛,只是意味着如果您改變了技術,您只需更改您的應用程序的1層。

如果您使用JPA,使用JPA的實體是一個很好的解決方案。除了這些實體,您可以擁有更多與GAE連接的「實體」(POJO)等。

關於抽象的狗和子類,除非真的需要,否則這似乎是一種矯枉過正的行爲。如果您真的需要,請檢查DTO對象:http://en.wikipedia.org/wiki/Data_transfer_object

DTO用於以一致的方式(並使其可序列化)將對象轉移到上層(上面的DAO),即使在處理多個數據源/技術時持久層。

2

JPA批註可以很好,因爲它們允許您將對象關係映射(ORM)元數據放置在與您的實體類相同的文件中,但是,當您結合使用JPA時存在混合關注元數據與「純粹」POJO。這是一個權衡。

然而,還有一種選擇。您可以將ORM配置外部化爲XML文件,並以這種方式將這些詳細信息保留在實體類之外。 JPA提供了XML配置語法,但對於我的項目,我更願意使用本機Hibernate XML映射來提高它們提供的靈活性。它可能不像基於註解的方法那樣流行,但根據我的經驗,它工作得很好。

2

您正確使用DAO層從其他圖層抽象數據源細節。因此,模型層實際上不知道使用哪種數據存儲技術或哪個數據庫。

您的問題的答案將是:使用服務層。這是您放置所有業務代碼的層。要實例化哪個實體,要使用哪個DAO,如何證實數據,事務劃分等。

因此,服務層應該加載/持久化實體。這就是你應該嵌入關於使用什麼數據源/數據庫的邏輯的地方。使用Spring的依賴注入來幫助你。將您選擇的DAO,實體注入服務層。

實體類:狗,貓

服務類:AnimalCenterService

DAO類:AnimalCenterHibernate,AnimalCenterJDBC

讓我知道,如果需要更多的解釋。 只是我的2美分

1

您不希望持久性特定的代碼從您的實體類繼承,因爲這會使您無法爲您的域實體類使用繼承。例如,如果你有HibernateDog繼承自Dog,那麼你不會讓Poodle繼承Dog而不強制Poodle成爲Hibernate特有的。

有效的一種方法是使用持久性特定的數據實體。您的域實體類將通過​​接口將其持久屬性委託給數據實體對象。只要符合您的數據實體接口,您就可以替換不同的持久性實現特定數據實體類。

狗引用(和代表)DogEntity接口。 貴賓犬繼承狗,PoodleEntity繼承DogEntity。

HibernateDog實現DogEntity
HibernatePoodle實現了PoodleEntity並從HibernateDog繼承。
...
StubDog實現DogEntity
StubPoodle實現PoodleEntity和StubDog
繼承...

您可以擁有任意數量的數據實體類型。數據實體將非常薄,只能保存持久化成員變量和註釋,或其他任何代碼是持久化所必需的。

域實體將包含實體特定的業務邏輯。