21

关于如何在 Hibernate 实体和要由 Web 服务返回的数据传输对象之间进行转换,我有类似的问题和担忧,如本问题所述:

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

这里提到的一个因素是,如果域模型发生变化,一组 DTO 将在 Web 服务的情况下保护消费者。

尽管它似乎会为我的项目添加大量代码,但这种推理似乎是合理的。

是否有一个好的设计模式可用于将 Hibernate 实体(实现接口)转换为实现相同接口的 DTO?

因此,假设以下两个都实现了“Book”,我需要将 BookEntity.class 转换为 BookDTO.class,以便让 JAXB 序列化并返回。

再一次,这整个前景对我来说似乎是可疑的,但如果有很好的模式可以帮助处理这种转换,我很想得到一些见解。

是否有一些有趣的方法可以通过反射进行转换?还是我没有想到的“建设者”模式?

我应该忽略 DTO 模式并传递实体吗?

4

5 回答 5

17

我应该忽略 DTO 模式并传递实体吗?

我的偏好通常是“是”。我不喜欢仅仅为了架构或层纯度而创建的并行层次结构的想法。

DTO 模式的最初原因是在将实体 EJB 传递到视图层时,EJB 1.0 和 2.0 应用程序中过多的闲聊。解决方案是将实体 bean 状态放入 DTO。

创建 DTO 通常给出的另一个原因是禁止视图层进行修改。在这种情况下,DTO 是不可变对象,没有任何行为。他们只是将数据传送到视图层。

我认为 DTO 是一种已成为反模式的核心 J2EE 模式。

我知道有些人会不同意。我只是提供我的意见。这不是唯一的方法,也不一定是“正确”的方法。这是我的偏好。

于 2010-12-29T22:02:32.870 回答
14

在 DTO 的所有欢乐中都需要有一个逆向的观点。

tl; dr - 它有时仍然有用。

DTO 的优点是您不必在域类中添加无数注解。

你从@Entity 开始。没那么糟糕。但是然后你需要 JAXB,所以你添加 @XMLElement 等 - 然后你需要 JSON,所以你添加诸如 @JsonManagedReference 之类的东西让 Jackson 用关系做正确的事情,然后你添加等等等等等等。

很快你的 POJO 就不再那么简单了。有时阅读“领域驱动设计”。

此外,您可以“过滤”一些您不想让视图知道的属性。

于 2011-07-26T16:27:13.517 回答
5

我们不应该忘记,实体对象在处于托管状态时并不容易处理。这使得它们传递到 GUI 表单有问题。更准确地说,子对象被急切地处理。这不能在会话之外完成,从而导致异常。因此,它们要么必须从实体管理器中驱逐(分离),要么必须转换为适当的 DTO。当然,除非有一种我不知道的模式,否则我会很高兴知道的。

于 2011-09-26T11:42:04.683 回答
4

为了快速创建一个“相似”的 DTO,无需一堆重复的 get/set 代码,您可以使用BeanUtils.copyProperties。该功能可帮助您快速将数据从 DAO 复制到 DTO 类。请记住,支持 BeanUtils.copyProperties 的常用库不止一个,但它们的语法并不相同。

于 2012-08-12T23:58:32.580 回答
2

我知道这是一个老问题,但我想我会添加一个答案,提供一个框架来帮助以防其他人解决这个问题。

我们的项目有 JAXB 注释的 POJO,它们与 JPA 注释的 POJO 是分开的。我们的团队正在讨论如何最好地在两个对象(实际上是数据结构)之间移动数据。

以下是供人们考虑的选项:

我们发现并正在试验Dozer,它处理 (1) 相同名称、(2) XML 映射和 (3) 自定义转换作为在两个 POJO 之间复制数据的方式。

到目前为止,它非常易于使用。

于 2015-02-10T23:14:41.147 回答