2012-01-07 89 views
8

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

现在我在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使用案例:我想显示用户名和相应的组它们所属的名称。像这个 -

名称 - >组名

凯沙夫 - >联系,最终用户,ReportAdmin
基兰 - > 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应该只对应于一个表,并且关联的对象应该聚合在应用层中。那对于从DB执行多个对象提取是否有开销?对于正确的方法过于困惑,抱歉这么长时间的解释!

回答

6

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

...但在一个典型的many-to-many relations你不需要第三个数据模型(UserGroupAssoc)。该User类将包含的Group个集合:

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

如果您还需要反向关系(一组包含用户)Group类将是这样的:

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

周而复始,这样做的经典方法是收集(UserGroup代替userIdgroupId)在使用“域对象”(DTO的你)。

您通常需要只有在关联表(User_Group_Association)含有比user_idgroup_id别的东西(也许这允许用户添加到组的一些授权码,等等)第三域对象:

user_id | group_id | auth_code 

在这种情况下,UserGroupAssoc类可能有这样的结构:

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

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

而且User和之间的许多一对多的关系将转换为与此新域对象的两个多对一关系。通常域对象是优选使用(UserGroup代替userIdgroupId)。

这是实现此方案的标准方法?

那么,如果您使用的是ORM框架,它将会是框架的标准方式。但是由于您有自定义的ORM解决方案,因此很难说

在DTO设计中加入表格是否正确?

为什么应用层中的DTO设计应该受数据库中表连接的影响?这是object-relational impedance mismatch的情况,也可能是law of leaky abstraction,因为您无法将关系域完全抽象为保持1:1对应关系的对象域。

有人认为一个DTO应该只对应于一个表,并且关联的对象应该聚合在应用层中。那对于从DB执行多个对象提取是否有开销?

ORM有一些限制(对于可能遇到的一些问题,请再次查看对象关系阻抗不匹配),并且很难模拟您的域对象以适应关系数据库的约束,反之亦然。报告就是这方面的典范。

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

每当DTO正好对应于数据库中的一个表,它是非常简单的

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

根据你在应用程序中的需求,你最终可能会看到一些奇怪的类或看起来很尴尬的SQL。您最终可能会运行更多的查询,而不是获取适当的对象模型以及它们之间的关联;或者您可能会使用更多类似的DTO来限制访问数据库的次数并获得更好的性能。

所以我想说的(再一次声明,我不是一个ORM专家)是不是所有的应用程序都是ORM的好候选人;但是如果你考虑继续研究它,可能会研究Hibernate/JPA如何解决这些问题,甚至可以继续使用它们。