在ejb3中使用数据传输对象被认为是最佳实践

时间:2009-07-06 09:28:02

标签: hibernate design-patterns java-ee ejb-3.0

虽然单个设计显然不能涵盖所有场景,但现在普遍认为ORM类应该在表示层和业务层(本地或远程)之间来回传递,从而取代了对数据传输对象的需求?据我所知,使用ORM类会出现不必要的急切加载,上下文管理问题和紧密耦合等问题,但也会节省大量时间并保持简单。现在是否存在一种标准方法,通常有利于一种方法(在大多数情况下)?

6 个答案:

答案 0 :(得分:4)

这是一个非常有趣的问题,我一直在调查和试验两年的通行证。

我认为这里确实没有正确或错误的答案。我不认为你可以简单地说我想要一个而不是另一个,因为通常你可能想要一个混合,取决于你的客户是什么(网页,ws,机器和/或本地,远程)。

这里要记住的重要一点是每个产品的优缺点是什么,并根据您的要求进行应用。

例如:

  • 如果您使用的是SEAM,那么您可能希望避免使用严重分层的体系结构,因为您可以访问扩展的持久性上下文。没有这种支持的其他网络技术往往会更好地与预先准备好状态的DTO一起工作。
  • 如果您要发送远程消息,导入的事情是保持它的轻薄,DTO通常比富域域对象更好用。在这里,您可以透明地抑制任何ORM问题/行为。
  • DTO模式的好处是可以保护您的客户免受域名更改。如果您的应用程序是一个Web服务,具有定义您的合同的域(实体)对象可能会让您在某个时刻失效,这一点尤为重要。

通过将系统分层并小心地暴露和保护它们,您可以为许多不同类型的客户生成各种API。

答案 1 :(得分:2)

紧耦合?请解释一下。

至于我,DTO是一种反模式。 EJB3允许我们省略使用它们。您可以在将实体发送到客户端之前强制执行延迟初始化。

当然,如果您只需要将30个字段中的两个发送给客户,您只需发送它们即可。但是,如果在我当前的项目中一直是整个副本 - 试图摆脱那个DTO。我认为没有理由使用它们。您可以在客户端询问时将业务对象发送到客户端。为什么要使用包装器?

答案 2 :(得分:1)

我认为DTO的存在与JPA / Hibernate 缺陷有关。如果您始终可以进行透明的延迟初始化,那么您将永远不会使用它们。所以使用DTO是一个合同,我的域/工作区总是丢失(到处复制)。 总结一下,你可以使用它们,但你必须讨厌它们:)

答案 3 :(得分:1)

我有几个问题反对在表示层使用实体:

  • 锁定:这最终会在您的演示文稿和模型之间产生严密的锁定。在大型项目中,改变也变得昂贵,甚至是不可能的。现代工具尚不存在。

  • 安全性:使用模型对象,您可以轻松地将各种数据库ID信息传输到您的网页。这是一个明显的安全问题。使用dto:s,您可以使用非常简单的会话地图在服务器上隐藏

  • 需求差异:GUI视图很少是模型对象的直接列表。更常见的是,他们是更多,结合了野兽, guish 。 GUI的需求往往会蔓延到模型中,使其模糊不清。

  • 速度:对于实体,每次读取/写入时都会处理每个字段。由于您将它们直接传递到表示层,因此您很难尝试优化JPA查询 - 几乎不可能。我肯定会回到直接使用JDBC -access - 就像myBatis在未来的项目中一样。因此消除了ORM。

我也遇到了DTO:s的问题:

  • 额外的DAO代码。

考虑到的事项,我会投票赞成对所有项目使用dto:s,同样取消JPA。所以,我的堆栈就像:

  • myBatis for database access
  • POJO作为DTO:s
  • 我的DAO服务的无状态EJB。
  • 用于GUI后端的StatefulEJB。
  • JSF for presentation。

答案 4 :(得分:0)

我同意最后一个“发言者”为什么在ejb3中使用包装器?我们构建了一个非常复杂的系统而没有DTO,但是使用它可以找到的实体(JPA)。很明显......

答案 5 :(得分:0)

如果GUI控制器将对象属性发送到表单而不是实体对象,那么

仅与实体一起工作会很好。另一方面,如果使用实体并且这些实体具有多对一关系,那么如果实体管理器不急切地获取实体,则应该期望看到一些令人讨厌的异常。

例如,在尝试填充Spring MVC的标签或其他GUI组件的类似构造时,可以观察到这种情况。

此外,DTO是放置额外注释的好地方,例如验证注释或JAXB等。