繁体   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