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

Rob*_*tis 5 java jsf spring hibernate dto

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

先感谢您.此致,罗伯托

Bal*_*usC 16

DTO代表数据传输对象.它应该是一个简单的vanilla Javabean类,没有任何API /体系结构特定的限制,如JSF,JPA或Spring注释.即它不应该包含import指向外部API的任何或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;
Run Code Online (Sandbox Code Playgroud)

很多库可以通过以下方式简化bean-to-bean映射:

SomeLibary.map(userEntity, userDTO);
Run Code Online (Sandbox Code Playgroud)

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

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

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

也可以看看:

  • 我想知道在没有 DTO 的情况下使用(休眠)延迟加载时是否会出现任何问题?考虑到我在 spring(事务)服务方法中获取一个父对象到延迟加载的子对象(即其他域对象的集合)的情况。在这种情况下,如何确保休眠会话保持打开状态,以便稍后(在 UI 层)获取休眠代理?如果我使用 DTO 并在服务方法中将数据映射到它们,那么我确定我拥有所有数据并且可以安全地关闭会话......对此有什么想法吗? (2认同)

Boz*_*zho 11

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

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

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