如何在JSF + Spring + Hibernate中使用DTO

假设我是关于主题DTO的新手。 我无法理解将DTO与JSF,Spring和Hibernate结合使用是否正确。
让我解释一下,到目前为止,我已经使用了直接从数据库创建的实体bean,无论是在业务层还是在表示层中。 现在我决定尝试使用DTO方法,但我无法理解他们如何提供帮助。
例如,如果我有两个类User和Message,并且用户有更多关联的消息; 如何从数据库中填充DTO? 或者我是否在业务层手动填充DTO? 谁可以发布一个如何使用DTO的例子?

先谢谢你。 此致,罗伯托

DTO代表数据传输对象。 它应该是一个简单的vanilla Javabean类,没有任何API /体系结构特定的限制,如JSF,JPA或Spring注释。 即它不应包含指向外部API的任何import或FQN。 唯一的目标是能够在大型模块化Web应用程序的不同体系结构之间传递数据。

例如,如果您不想将JPA / Hibernate实体bean用作JSF托管bean和视图的模型属性,因为由于某些过于严格的业务或模块化原因,它们可能无法传递到EJB类之外,那么您需要创建此类的副本并自己映射松散属性。 基本上:

 UserEntity userEntity = em.find(UserEntity.class, id); UserDTO userDTO = new UserDTO(); userDTO.setId(userEntity.getId()); userDTO.setName(userEntity.getName()); // ... return userDTO; 

有大量的库可以通过以下方式简化bean-to-bean映射:

 SomeLibary.map(userEntity, userDTO); 

但是,对于普通的Web应用程序,您不需要DTO。 您已经在使用JPA实体了。 您可以继续在JSF bean / view中使用它们。

仅此问题已经表明您实际上根本不需要DTO。 您没有被某些特定的业务限制所阻止。 然后,您不应该搜索设计模式,以便可以将其应用于项目。 您应该以过度复杂/不可维护/重复的代码的forms搜索实际问题,以便您可以为其寻找/找到合适的设计模式。 通常,重构重复代码几乎会自动引入新的设计模式,而无需您实际意识到它。

一个很好的例子是当JPA实体对于特定目的而言“太大”时(即实体包含比实际需要的更多的属性)。 拥有大量这些部分使用的实体是浪费服务器内存。 要解决此问题,您可以仅使用您在JPQL中使用构造函数表达式创建和填充的一些属性来创建DTO类/子类。

也可以看看:

  • DAO和JDBC的关系?
  • JSF控制器,服务和DAO
  • JSF服务层

填充DTO有两种选择 – 手动或使用commons-beanutils或Dozer等实用程序。

DTO背后的一般思想是,它们用于跨架构层传输数据 – 通常是松散耦合的层,例如通过Web服务或JMS。 DTO也可以在视图中使用,以便web层获取可以用于向用户显示的对象,这些对象与实体不同,以避免实体状态管理问题和映射混乱。

但对于典型应用,我认为DTO是不必要的。 在JSF bean和视图中使用您的实体,只需注意可能的LazyInitializationException 。 我的经验表明,在大多数情况下,实体可以用作DTO(不需要新类),稍微小心点。 无论我在小型项目中看到DTO,他们只会不必要地复杂化。