【问题标题】:DTO to Entity And Entity to DTODTO 到实体和实体到 DTO
【发布时间】:2012-12-16 06:57:52
【问题描述】:

我们将使用 DTO 向表示层发送数据和从表示层发送数据。 我们有这样的层:

  • 立面
  • 应用服务

我们已经使用 Dozer 帮助我们将实体转换为 dto。 但我现在有两个问题:

  1. 从entity到dto可以使用dozer,但是从dto到entity可以使用dozer吗?如果是,如何?
  2. 我应该在哪里创建实体?在门面或 DTOAssembler 中?

例如,我必须注册一本书。这本书实体看起来像:

Book{
   public Book(BookNumber number,String name){
      //make sure every book has a business number,
      //and the number can't change once the book is created.
      this.bookNumber = number;
      ..
   }
}

我们有一个 DTOAssembler:

BookDTOAssembler{

  BookDTO toDAO(bookEntity){
  ...
  }
  BookEntiy fromDTO(book DTO,BookRepository bookRepository){
    //1.Where should i create book entity? 
    //2.Is there any effective way to convert dto to entity in java world?
  }
}

选项 1

the BookManagedFacade has a registerBook function:
public registerBook(bookDTO){
   Book book = BookDTOAssembler.fromDTO(book DTO);
}

//Create book in BookDTOAssembler.fromDTO 
public static BookEntiy fromDTO(BookDTO bookDTO,BookRepository bookRepository){
    //book is never registered 
    if (0==bookDTO.getBookID()){
       Book book = new Book(bookRepository.generateNextBookNumber(),bookDTO.getName());
    }else{
       //book is been registed so we get it from Repository
       book = bookRepository.findById(bookDTO.getBookID()); 
    }
    book.setAuthor(bookDTO.getAuthor);
    ...
    return book;
}

选项 2

the BookManagedFacade has a registerBook function:
public registerBook(bookDTO){
   Book book = new Book(bookRepository.generateNextBookNumber(),bookDTO.getName());
   book = BookDTOAssembler.fromDTO(book DTO,book);
}

//add another function in BookDTOAssembler.fromDTO 
public static BookEntiy fromDTO(BookDTO bookDTO,Book book){
    book.setAuthor(bookDTO.getAuthor);
    ...
    return book;
}

一个更好?或者它可以以更好的方式实现..?

【问题讨论】:

  • 坦率地说,我会远离推土机。我们在我当前的项目中使用它,我讨厌它:它迫使你手动做一些事情,或者通过添加不应该存在的 setter 来完全破坏对象的封装。无论如何,一些操作必须在没有它的情况下完成。最大的问题是:如果你碰巧重命名了一个属性,一切都会编译得很好,但只会在运行时产生不正确的结果。将 DTO 转换为实体,反之亦然,虽然很简单。手动执行此操作可确保保留封装,并允许重构。
  • 这是真的!如果有任何变化,可以在运行时找到!您对我的问题 2 有何建议?
  • 我更喜欢有一种方法,只从 BookDTO 复制到 Book,而不关心 Book 来自哪里。
  • 你更喜欢fromDTO(BookDTO bookDTO,Book book)?
  • 关于运行时错误 - 您可以编写测试实体/dto之间的转换。

标签: hibernate domain-driven-design dozer


【解决方案1】:

通常您不会将对象(域实体的 DTO 表示)传输回服务器。因为如果你这样做,你会破坏封装,因为任何人都可以将更改应用到 DTO,然后将信息发回。

相反,您应该创建一个用于修改对象的服务接口,因为它允许 服务器 将更改应用到它的模型。

所以服务实际上分为两部分:

  1. 用于获取所有实体的 DTO 表示的查询部分
  2. 用于将更改应用于实体的命令部分

【讨论】:

  • 不错的答案。我同意。但是,我认为您发送回服务器的仍然是 DTO。不同之处在于您不会将 DTO 映射回域实体。相反,正如您所说,DTO 代表您希望应用于现有实体的命令。对于创建新实体的命令,DTO 将提供创建所述实体所需的数据。
  • 是的。我只是说你不应该发回代表域实体中所有信息的 DTO。
  • 是的,我知道你在谈论 cqrs..但是在这个时候,我们没有 cqrs 实现..所以..如果我在书中有很多属性,如何通过这些属性到服务接口?还是应该提供'updateName(),updateAuthor()..updatexxx'之类的接口,客户端一一调用这个接口?
猜你喜欢
  • 2021-06-16
  • 1970-01-01
  • 2018-09-13
  • 2020-07-23
  • 1970-01-01
  • 2017-09-17
  • 2011-08-20
  • 2021-10-28
相关资源
最近更新 更多