9

我正在为 Web 应用程序使用 Java + Spring 框架。我没有使用任何 ORM 工具。相反,我试图使用简单的 DAO/DTO 模式将数据库关系建模为 Java 对象。只要 DTO 与数据库中的单个表完全对应,它就非常简单。但是如果有表使用外键引用其他表,我不确定什么是最好的方法。在 Stackoverflow 中寻找类似的答案,但找不到我需要的答案。我想举一个非常具体的例子——假设有两个实体用户和组。我有一个用户 DTO 和一个组 DTO,每个 DTO 分别有 UserDao(JdbcUserDao) 和 GroupDao(JdbcGroupDao)。

现在我在数据库中有一个连接用户和组的关系。一个用户可以属于多个组。表名为 User_Group_Association,具有以下 DB 定义:

用户 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 -> 管理员、最终用户、ReportAdmin
Kiran -> ReportAdmin
Pranav -> 最终用户

在第一种 DTO 设计方法中,我需要再次从数据库中获取用户详细信息(名称)和组详细信息(名称)。在第二种方法中,当我构建 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 应该只对应一个表,关联的对象应该聚合在应用层。那有从数据库中获取多个对象的开销吗?对正确的方法太困惑了,抱歉这么长的解释!

4

1 回答 1

6

免责声明:我不是 ORM 专家......

...但在经典的多对多关系中,您不需要第三个数据模型 ( UserGroupAssoc)。该类User将包含Groups 的集合:

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

如果您还需要反向关系(一个组包含用户),则Group该类将如下所示:

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

再一次,经典的做法是在集合中使用“域对象”(你的 DTO)(UserGroup不是userIdand groupId)。

User_Group_Association只有当关联表 ( ) 包含除user_idand以外的其他内容时,您通常才需要第三个域对象group_id(可能是一些允许将用户添加到组的授权代码,无论如何):

user_id | group_id | auth_code

在这种情况下,UserGroupAssoc该类可能具有以下结构:

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

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

User和之间的多对多关系Group将转换为与这个新领域对象的两个多对一关系。通常首选使用域对象(UserandGroup而不是userIdand groupId)。

实现这种情况的标准方法是什么?

好吧,如果您使用的是 ORM 框架,那将是该框架执行此操作的标准方式。但是既然你有一个自定义的 ORM 解决方案,那就很难说。

在 DTO 设计中加入表格好吗?

为什么应用层的 DTO 设计会受到数据库中的表连接影响?这是对象关系阻抗不匹配的情况,也可能是泄漏抽象定律,因为您无法将关系域完全抽象为保持 1:1 对应关系的对象域。

有人认为,一个 DTO 应该只对应一个表,关联的对象应该聚合在应用层。那有从数据库中获取多个对象的开销吗?

ORM 有一些限制(再次查看对象关系阻抗不匹配以了解您可能遇到的一些问题)并且很难对域对象进行建模以适应关系数据库的约束,反之亦然。报告是这方面的一个很好的例子。

报告通常会聚合来自多个表的数据。这对于某些 SQL 连接当然没有问题,但是您将如何将结果映射到 DTO?正如你自己所说...

每当 DTO 完全对应于数据库中的单个表时,它就非常简单

...但报告结果不会映射到单个表,它必须映射到更多表的片段。

根据您在应用程序中的需求,您最终可能会得到一些看起来很奇怪的类或看起来很尴尬的 SQL。您最终可能会运行比获取正确对象模型和它们之间的关联所需的更多的查询;或者您可能有更多类似的 DTO,只是为了限制访问数据库的次数并获得更好的性能。

So what I'm trying to say (again the disclaimer that I'm not an ORM specialist) is that not all applications are a good candidate for ORM; but if you consider going ahead with it maybe look into how Hibernate/JPA is addressing the issues or even go ahead and use them instead.

于 2012-01-08T11:41:31.353 回答