欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

dto与dto相互转换_在DTO上

发布时间:2023/12/3 编程问答 46 豆豆
生活随笔 收集整理的这篇文章主要介绍了 dto与dto相互转换_在DTO上 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

dto与dto相互转换

通常使用DTO或数据传输对象 。 什么不是s? 众所周知,它们源自DDD(域驱动设计)。 在那里很有意义–域对象具有状态,身份和业务逻辑,而DTO仅具有状态。

但是,当今许多项目正在使用贫血数据模型方法( 我认为 ),并且仍在使用DTO。 每当对象“离开”服务层或“离开”系统时(通过Web服务,rmi等),都将使用它们。 有三种方法:

  • 每个实体至少具有一个对应的DTO。 对于视图层中的不同方案,通常不止一个。 在列表中显示用户时,您会有一个DTO,而在“用户详细信息”窗口中显示时,则需要一个扩展的DTO。 我不赞成这种方法,因为在很多情况下,DTO和域结构具有完全相同的结构,因此,存在很多重复的代码+冗余映射。 另一件事是多个DTO的可变性。 即使它们与实体不同,它们在一个或两个字段之间也彼此不同。 为什么重复是一件坏事? 因为要在两个地方进行更改,所以当数据通过多个对象时,很难跟踪问题,并且因为它是重复的。 在同一项目中复制和粘贴是一种罪过。
  • 仅当DTO的结构与实体的结构明显不同时才创建DTO。 在所有其他情况下,都使用实体本身。 您不希望显示某些字段的情况(尤其是在通过Web服务公开给第三方的情况下)存在,但并不常见。 有时可以通过序列化机制来处理(例如,将其标记为@JsonIgnore@XmlTransient) ,但在其他情况下,结构则有所不同。 在这些情况下,应有DTO。 例如,您有一个User和UserDetails,其中UserDetails保存详细信息+当前登录用户与给定用户的关系。 后者与实体无关,因此您创建一个DTO。 但是,对于DirectMessage,在数据库和UI中都具有发件人,收件人,文本和日期时间。 无需DTO。

    使用此方法的一个警告(以及下一个警告)。 贫血的实体通常带有ORM(对于Java,则为JPA)。 每当它们退出服务层时,由于需要开放会话的惰性集合,它们可能无效。 您在这里有两个选择:

    • 使用OpenSessionInView / OpenEntityManagerInView –这样,会话将保持打开状态,直到您准备好响应为止。 这很容易配置,但不是我的首选-它以一种微妙的方式违反了层边界,这有时会导致问题,特别是对于新手开发人员
    • 不要使用惰性集合。 不需要延迟收集。 如果他们应该保留一小部分项目(例如,用户角色列表),或者如果数据可能会增长而使用查询,要么让他们渴望。 是的,无论如何您都不会显示1000条记录,您必须对其进行分页。 如果没有惰性关联(默认情况下@@ ToOne渴望),则在关闭会话时不会有无效的对象
  • 完全不使用DTO。 没有明显变化的结构,请尽快应用。 对于较小的项目,这通常是一个好方法。 上面提到的所有内容都适用于此。

因此,我首选的方法是“ 中间方法 ”。 但是在每种情况下都需要考虑很多因素,这可能不适用于规模较大和/或经验较少的团队。 因此,应该选择两个“极端”之一。 由于还需要考虑“无DTO”方法-做@Transient是什么,惰性集合如何影响流量等,因此通常选择“所有DTO”。 但是,尽管这似乎是最安全的方法,但仍有很多陷阱。

首先,您如何从DTO映射到实体,反之亦然? 三种选择:

  • 专用的映射器类
  • 构造函数– DTO构造函数接受实体并填充自身,反之亦然(记住也要提供默认的构造函数)
  • 声明性映射(例如Dozer )。 这实际上与第一个选项相同–它外部化了映射。 它甚至可以与专用的映射器类一起使用
  • 串联映射它们(必要时)。 这可能会生成无法维护的代码,因此不是首选

我更喜欢构造方法,至少是因为创建的类更少。 但是它们本质上是相同的(DTO并不以封装闻名,因此您的所有属性无论如何都公开)。 这是使用DTO和两种“映射”方法时的准则列表:

  • 不要生成过多的冗余代码。 如果两种情况需要稍微不同的DTO,请重用。 无需为一两个字段之间的差异创建新的DTO
  • 不要将表示逻辑放在映射器/构造函数中。 例如,如果( entity.isActive()dto.setStatus(“ Active”); 这应该在视图层中发生
  • 不要将实体与DTO一起偷偷摸摸。 DTO不应具有作为实体的成员。 通常,不应在服务层之外使用实体(这有点极端,但是如果我们在所有地方都使用DTO,则应该保持一致并坚持这种做法)
  • 不要在控制器中使用mappers / entity-to-dto构造函数,而在服务层中使用它们。 首先使用DTO的原因是实体可能是ORM绑定的,并且它们可能在会话外部(即服务层外部)无效。
  • 如果使用映射器,则首选静态映射器方法。 映射器没有状态,因此不需要实例化它们。 (而且不必嘲笑,包装等)。
  • 如果使用映射器,则无需为每个实体(+多个DTO)使用单独的映射器。 可以将相关实体分组在一个映射器中。 例如CompanyCompanyProfileCompanySubsidiary可以使用相同的映射器类

只需确保在项目开始时就做出所有这些决定,然后确定哪种情况适用于您的方案(团队规模和经验,项目规模,领域复杂性)。

参考: 在的DTO从我们JCG伙伴 Bozho在Bozho的科技博客 。

相关文章 :

  • Spring和AspectJ的领域驱动设计
  • 在域驱动设计中使用状态模式
  • ORM问题
  • 什么是依赖倒置? 是IoC吗?
  • 框架使开发人员愚蠢吗?
  • 每个程序员都应该知道的事情
  • JDK中的设计模式
  • Java最佳实践

翻译自: https://www.javacodegeeks.com/2011/09/on-dtos.html

dto与dto相互转换

总结

以上是生活随笔为你收集整理的dto与dto相互转换_在DTO上的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。