2015-09-11 45 views
0

我以前使用Hibernate/JPA,現在使用Spring JDBC和MyBatis的組合。JDBC域設計和關係

使用JPA/Hibernate,如果您有一個客戶,其中有一個地址,您將擁有類似於以下代碼的域結構。 (減去所有註釋/配置/映射)。

當使用JDBC或MyBatis時,這仍然有意義嗎?這是從我所知道的,擁有一個,所屬的等等組成的領域設計。然而,我所看到的大多數JDBC代碼示例中,他們都具有域對象,它們可以帶回ID而不是集合,或者使數據變平。是否有任何性能方面的好處,可維護性等。與JPA一起工作,我不知道什麼是JDBC的做事方式。

public class Customer { 

    private Long id; 
    private String userName; 
    private String password; 
    private String firstName; 
    private String lastName; 
    private Collection<Address> addresses 
    ... 
} 

public class Address { 
    private Long id; 
    private String streetAddress1; 
    private String streetAddress2; 
    private String city; 
    private State state; 
    private String postalCode; 
} 

public class State { 
    private Long id; 
    private String code; 
    private String name; 
    private Country country; 
} 

public class Country { 
    private Long id; 
    private String code; 
    private String name; 
} 

我遇到了一個例子,這裏是他們的一個類。

public class Question { 
    private long questionId; 
    private long categoryId; 
    private long userId; 
    private long areaId; 
    private String question; 
    private String verifyKey; 
    private Date created; 
    private User user; 
    private List<Answer> answers; 
    private long answerCount; 
    private String name; 
    // getters and setters omited... 
} 

爲什麼要獲取userId,areaId和categoryId而不是實際獲取關聯的對象?該ID可能對前端用戶沒有用處,我想你可以使用該ID來發出另一個查詢來獲取額外的數據,但似乎效率低下,再往返數據庫。

回答

0

您可以將此域對象視爲數據庫表的「足跡」。在你的例子中,userId,areaIdcategoryId from Question很可能是相應表中的外鍵。在創建問題的時候,您永遠不需要完整的對象數據,以後可以使用單獨的數據庫請求進行檢索。如果您一次獲取所有關聯的對象,則每個對象至少會添加一個附加表(通過join-s或subselect-s)。而且,這實際上和Hibernate一樣。默認情況下,如果需要未初始化的關聯對象,它會延遲加載域對象並再次點擊數據庫。

那時候,最好是獲取那些沒有域對象就不能存在的對象。在你的例子中,問題和列表是耦合的。當然,如果您在某個其他應用程序位置(假設之前檢索到的對象的引用已丟失)中再次需要用戶,類別或任何其他關聯對象,那麼您將使用相同的查詢命中數據庫。應該這樣做,看起來效率不高,因爲普通的JDBC和SpringJDBC都不像Hibernate那樣有中間緩存。但這不是JDBC設計的目的。

+0

你是什麼意思「你可以看看這個域對象作爲數據庫表的」足跡「?如果我正確地理解了你的域,這個域與數據庫沒有1比1,但應該是相似的。作爲地址對象的一個​​例子,它沒有任何狀態存在是沒有意義的,因此而不是stateId它應該引用狀態對象? – greyfox

+0

對不起,我並不是說要問域對象,而是第一個語句中的Question類。 地址和狀態如何,取決於它們在您的應用程序中的典型用法。在大多數情況下通過地址對象使用狀態對象?如果不是,那麼有什麼需要初始化它? 當然,您可以堅持_State_字段而不是_stateId_並將其保留爲'null'。但是我個人不會那樣做。它混淆了開發人員期望一個State對象被初始化,並且還需要在整個代碼中進行空檢查。 – Grade

+0

那麼n + 1問題呢,比如我需要返回100個地址到UI,並且它需要顯示狀態名,而不是Id,現在你運行一個查詢來獲取所有的地址行,然後發出另一個查詢行以獲得總共101個查詢的狀態,這對於JDBC來說可以接受嗎?您收集的子集越多,得到的差越大 – greyfox