【问题标题】:DTO and Entity in one object?DTO 和实体在一个对象中?
【发布时间】:2015-07-01 15:02:48
【问题描述】:

我目前处于两难境地,我一直在阅读有关此的内容。

我正在让我的 DTO 也成为我的实体。它看起来像这样:

@Entity
@PasswordMatches // custom validator
public class User {

    @Id
    @Column
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;

    @Column
    @NotNullOrEmpty // custom validator
    private String password;

    @Transient
    @NotNullOrEmpty // custom validator
    private String confirmPassword;

Q1:这是可以接受的还是有更好的方法呢?因为目前,在保存User 之前,出于显而易见的原因,我正在对密码进行哈希处理,但如果我直接使用em.persist(user),它将因为@PasswordMatches 失败而失败。只有当我为了满足验证而做user.setConfirmPassword(hashedPassword) 时,它才会节省。我在这里做对了吗?

【问题讨论】:

    标签: spring validation jpa


    【解决方案1】:

    虽然 EJB3 允许将实体用作 DTO,但事实是拥有单独的 DTO 仍然更好。

    很快您会发现您的实体将需要与特定 JPA 提供程序(如 Hibernate)相关的注释,这会将您的实体与持久层联系起来。这意味着如果您的实体被“向上”传递到您的表示层,那么该层需要“了解”您在持久层中使用的特定库/框架。如果您在做 Web 工作,这不是什么大问题,但如果您在做富客户端(例如 Swing),那么这可能是您的客户需要随身携带的额外包袱。

    同样,您将要开始为表示层注释您的实体(例如,使用@Json 注释)。将这些放入您的实体中将再次将您的持久层与您的表示层联系起来。

    最初,我们陷入了使用实体将数据传递给富客户端的陷阱,但当我们意识到需要将它们分成 DTO 和持久实体时,我们已经创建了 300 多个实体类。使用这么多实体这样做是一种痛苦的经历,但现在(拥有 400 多个实体类)我们很高兴我们做到了。

    因此,虽然您正在做的事情可以接受的,但您已经遇到了一个问题,即将业务逻辑与持久层混合会导致问题。我建议您将它们分成 DTO 和实体,以免您在未来继续遇到问题。

    【讨论】:

    • 这种见解非常有帮助。我现在也倾向于为此使用 DTO。但是为了记录,你在 DTO 和实体之间有 1-1 的对应关系吗?您是手动进行映射还是使用某些东西来映射 DTO->Entity,反之亦然?
    • 我们的 DTO 大多是 1-1,但它们可能具有仅表示/业务层使用的字段。有无数种方法可以从实体创建 DTO。您可以使用注释处理或 Dozer 等第三方实用程序,但我们使用自定义 Perl 脚本来解析实体并创建(除其他外)相应的 DTO。
    • @Incognito 你能告诉我你不接受我的回答有什么问题吗?
    • 对不起,我认为有必要开一个赏金。至少在赏金之前再次选择它作为最佳答案。
    【解决方案2】:

    从短期来看,它似乎很有成效,可以帮助您更快地完成工作。

    从长远来看,将 DTO 和实体分开总是更好。

    随着实体之间的关系增长,您会意识到获取一个实体也会导致子实体也被获取,即使您在该特定用例中可能不需要它们。 DTO 可帮助您以您需要的方式优化数据库查询,使基础实体对业务用例隐藏。

    【讨论】:

      【解决方案3】:

      答案还取决于您的用例。考虑这些因素

      1. 如果您预期,将来将您的服务层公开给各种客户端。在这种情况下,将您的实体设计共享为服务方法签名的一部分,这不是一个好主意,这也可能会给可扩展设计带来问题。
      2. 如果您正在开发一个小型/医疗应用程序,并且将性能放在首位,您可以只使用从服务层(甚至是表示层)到持久层的实体。实体可以在 xml 中定义持久性特定配置,而不是通过注释。如果您在 DTO 和实体之间进行了一对一的映射,这并不是一个糟糕的设计。当然,在这种情况下,您将拥有更快的开发速度和更少的错误。
      3. 如果您打算为表示层(表单 bean)保留单独的 bean,您也可以考虑混合使用。例如,对于主实体管理模块 - 使用实体和无 DTO。对于事务实体管理模块 - 使用实体和 DTO。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-12-06
        • 2021-06-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-06
        相关资源
        最近更新 更多