簡體   English   中英

設計具有外鍵關系的DTO

[英]Designing DTOs that have foreign key relationships

我正在使用Java + Spring框架來處理Web應用程序。 我沒有使用任何ORM工具。 相反,我試圖使用簡單的DAO / DTO模式將db關系建模為Java對象。 每當DTO完全對應於數據庫中的單個表時,它就非常直接。 但是如果有表使用外鍵引用其他表,我不確定這是什么最好的方法。 在Stackoverflow中查找類似的答案,但找不到我的需求。 我想舉一個非常具體的例子 - 假設有兩個實體User和Group。 我有一個User DTO和Group DTO,每個都有UserDao(JdbcUserDao)和GroupDao(JdbcGroupDao)。

現在我在DB中有一個連接用戶和組的關系。 一個用戶可以屬於多個組。 表名是User_Group_Association,具有以下數據庫定義:

user_id | GROUP_ID

這里user_id是引用用戶表的外鍵。 類似地,group_id指的是組表。 當我用Java模擬這個DTO時,我應該這樣做:

public class UserGroupAssoc {
    private int userId;
    private int groupId;

    //Setters and getters follow
}

或者它應該是這樣的:

public class UserGroupAssoc {
    private User user;
    private Group group;

    //Setters and getters follow
}

特定UI用例:我想顯示用戶名及其所屬的相應組名。 像這樣的東西 -

名稱 - >組名

Keshav - > Admin,EndUser,ReportAdmin
Kiran - > ReportAdmin
Pranav - > EndUser

在第一種DTO設計方法中,我需要再次從DB中獲取用戶詳細信息(名稱)和組詳細信息(名稱)。 在第二種方法中,我需要在構建UserGroupAssoc對象本身時獲取User和Group對象。

在第三種方法中,我可以按如下方式設計UserGroupAssoc DTO:

public class UserGroupAssoc {
    private String userName;
    private String groupName;
    private int userId;
    private int groupId;

    //Setters and getters follow
}

在第三種方法中,我在SQL中連接表以僅獲取用例所需的字段,然后相應地為DTO建模。

實現此方案的標准方法是哪種? 在DTO設計中加入表格是否合適? 有些人認為一個DTO應該只對應一個表,關聯的對象應該在應用層聚合。 這有從DB進行多個對象提取的開銷嗎? 對於正確的方法感到困惑,抱歉這么長的解釋!

免責聲明:我不是ORM專家......

...但是在經典的多對多關系中,您不需要第三個數據模型( UserGroupAssoc )。 User類將包含Group s的集合:

public class User {
   // ... user fields ...
   List<Group> groups;
   // ... getters/setters ...
}

如果還需要反向關系(一個組包含用戶), Group類將如下所示:

public class Group {
   // ... group fields ...
   List<User> users;
   // ... getters/setters ...
}

再一次,這樣做的經典方法是在集合中使用“域對象”(您的DTO)( UserGroup而不是userIdgroupId )。

僅當關聯表( User_Group_Association )包含除user_idgroup_id之外的其他group_id (可能是允許將用戶添加到組中的某些授權代碼,無論如何)時,通常只需要第三個域對象:

user_id | group_id | auth_code

在這種情況下, UserGroupAssoc類可能具有以下結構:

public class UserGroupAssoc {
    private User user;
    private Group group;
    private String authorizationCode;

    // ... setters/getters ...
}

UserGroup之間的多對多關系將轉換為與這個新域對象的兩個多對一關系。 通常,首選使用域對象( UserGroup而不是userIdgroupId )。

實現此方案的標准方法是哪種?

好吧,如果您使用的是ORM框架,它將是框架執行它的標准方式。 由於您有自定義ORM解決方案,因此很難說。

在DTO設計中加入表格是否合適?

為什么應用層中的DTO設計會受到數據庫中表的連接的影響? 這是對象 - 關系阻抗不匹配的情況 ,也可能是泄漏抽象定律,因為您無法將關系域完全抽象為保持1:1對應關系的對象域。

有些人認為一個DTO應該只對應一個表,關聯的對象應該在應用層聚合。 這有從DB進行多個對象提取的開銷嗎?

ORM有一些限制(再次看到您可能遇到的某些問題的對象 - 關系阻抗不匹配),並且很難對域對象進行建模以適應關系數據庫的約束,反之亦然。 報告就是這個方向的好例子。

報告通常聚合來自多個表的數據。 對於某些SQL連接,這當然沒有問題,但是如何將結果映射到DTO? 正如你自己說的那樣......

每當DTO完全對應於數據庫中的單個表時,它就非常直接

...但是報告結果不會映射到單個表,它必須映射到更多表中的片段。

根據您在應用程序中的需求,您最終可能會看到一些看起來很奇怪的類或者看起來很笨拙的SQL。 您最終可能會運行比查詢所需的更多查詢以獲取正確的對象模型和它們之間的關聯; 或者你可能有更多類似的DTO只是為了限制到數據庫的次數並獲得更好的性能。

所以我想說的是(我不是ORM專家的免責聲明)並非所有應用程序都是ORM的良好候選者; 但是如果你考慮繼續它可能會考慮Hibernate / JPA如何解決這些問題,甚至可以繼續使用它們。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM