假设我是DTO主题的新手。我不明白将DTO与JSF、Spring和Hibernate结合使用是否正确。让我解释一下,到目前为止,我在业务层和表示层中都使用了直接从数据库创建的实体bean。现在我决定尝试使用DTO方法,但我不明白它们有什么帮助。
例如,如果我有两个类User和Message,并且一个用户有更多关联的消息;如何从数据库填充DTO ?还是在业务层手动填充DTO ?有人可以张贴一个例子,如何使用DTO?
提前谢谢你。问候,罗伯特。
DTO代表数据传输对象。它应该是一个普通的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到bean的映射:
SomeLibary.map(userEntity, userDTO);
然而,对于一般的web应用程序,你不需要dto。您已经在使用JPA实体。您可以在JSF bean/视图中继续使用它们。
这个问题本身已经表明你实际上根本不需要dto。您不会受到某些特定业务限制的阻碍。然后,您不应该搜索设计模式,以便将其应用于您的项目。您应该以过于复杂/不可维护/重复的代码的形式搜索真正的问题,以便您可以询问/找到适合它的设计模式。通常,重构重复的代码几乎会自动引入新的设计模式,而无需您实际实现它。
一个很好的例子是JPA实体"太大"。对于特定的目的(例如,实体包含的属性比你实际需要的多得多)。拥有大量这些部分使用的实体是对服务器内存的浪费。为了解决这个问题,您可以创建一个DTO类/子类,仅基于它的几个属性,您可以使用JPQL中的构造函数表达式创建和填充这些属性。
参见:
- DAO和JDBC关系?
- JSF控制器、服务和DAO JSF服务层
有两种方法可以填充dto——手动填充,或者使用common_beanutils或Dozer等实用工具。
dto背后的一般思想是,它们用于跨架构层传输数据——最常见的是松散耦合的层,例如通过web服务或JMS。dto也可以用在视图中,这样web层就可以得到不同于实体的对象,用来显示给用户,以避免实体状态管理问题和映射混乱。
但是对于典型的应用程序,我认为dto是不必要的。在JSF bean和视图中使用您的实体,只是要小心可能的LazyInitializationException
。我的经验表明,在大多数情况下,实体可以用作dto(不需要新的类),稍微小心一点。无论我在哪个小项目中看到dto,他们只会把不必要的事情复杂化。