java 如何在 JSF + Spring + Hibernate 中使用 DTO
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5722036/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use DTO in JSF + Spring + Hibernate
提问by Roberto de Santis
Assuming that i'm new about the topic DTO.
I can't understand if it is correct to use the DTO in tandem with JSF, Spring and Hibernate.
Let me explain, so far I have used the entity bean, created directly from the database, both in business layer and in the presentation layer.
Now I decided to try using the DTO approach, but I can not understand how they can help.
For example if I have two classes User and Message, and a user has more messages associated; how can I populate the DTO from the database? Or do I manually populate the DTO at the business layer?
can someone post an example on how to use DTO?
假设我是 DTO 主题的新手。我不明白将 DTO 与 JSF、Spring 和 Hibernate 一起使用是否正确。
让我解释一下,到目前为止,我在业务层和表示层都使用了直接从数据库创建的实体 bean。现在我决定尝试使用 DTO 方法,但我无法理解它们如何提供帮助。
例如,如果我有两个类 User 和 Message,并且一个用户关联了更多消息;如何从数据库中填充 DTO?还是我在业务层手动填充 DTO?有人可以发布有关如何使用 DTO 的示例吗?
Thank you in advance. Regards, Roberto
先感谢您。问候, 罗伯托
回答by BalusC
DTO stands for Data Transfer Object. It's supposed to be a plain vanilla Javabean class without any API/architecture specific restrictions such as JSF, JPA or Spring annotations. I.e. it should not contain any import
or FQN pointing to an external API. The sole goal is to be able to pass data between different architectures of a big modular webapplication.
DTO 代表数据传输对象。它应该是一个普通的 Javabean 类,没有任何 API/架构特定的限制,例如 JSF、JPA 或 Spring 注释。即它不应包含import
指向外部 API 的任何或 FQN。唯一的目标是能够在大型模块化 Web 应用程序的不同架构之间传递数据。
For example, if you don't want to use a JPA/Hibernate entity bean as model property of a JSF managed bean and view because they may not be passed beyond the EJB class due to some overly restrictive business or modularity reasons, then you need to create a copy of this class and map the loose properties yourself. Basically:
例如,如果您不想使用 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;
There are plenty of librariesavailable which makes bean-to-bean mapping easy in following way:
有很多可用的库可以通过以下方式轻松实现 bean 到 bean 的映射:
SomeLibary.map(userEntity, userDTO);
However, for the average webapplication you don't need DTOs. You're already using JPA entities. You can just go ahead with using them in your JSF bean/view.
但是,对于一般的 Web 应用程序,您不需要 DTO。您已经在使用 JPA 实体。您可以继续在 JSF bean/视图中使用它们。
This question alone already indicates that you actually don't need DTOs at all. You are not blocked by some specific business restrictions. You should not then search for design patterns so that you can apply it on your project. You should rather search for real problems in form of overcomplicated/unmaintainable/duplicated code so that you can ask/find a suitable design pattern for it. Usually, refactoring duplicate code almost automatically introduces new design patterns without you actually realizing it.
仅此问题就已经表明您实际上根本不需要 DTO。您不会被某些特定的业务限制阻止。然后你不应该搜索设计模式,以便你可以将它应用到你的项目中。您应该以过于复杂/不可维护/重复的代码的形式搜索真正的问题,以便您可以为其询问/找到合适的设计模式。通常,重构重复代码几乎会自动引入新的设计模式,而您并未真正意识到。
A good example is when a JPA entity is "too large" for the particular purpose (i.e. the entity contains way much more properties than you actually need). Having a lot of those partially used entities is a waste of server memory. To solve this, you could create a DTO class/subclass based on only a few of its properties which you create and fill using constructor expressionin JPQL.
一个很好的例子是当 JPA 实体对于特定目的“太大”时(即实体包含的属性比您实际需要的多得多)。拥有大量那些部分使用的实体会浪费服务器内存。为了解决这个问题,您可以仅基于使用JPQL 中的构造函数表达式创建和填充的几个属性来创建 DTO 类/子类。
See also:
也可以看看:
回答by Bozho
There are two options for populating DTOs - manually, or using an utility like commons-beanutils or Dozer.
有两种填充 DTO 的选项 - 手动,或使用 commons-beanutils 或 Dozer 等实用程序。
The general idea behind DTOs is that they are used to transfer data across layers of the architecture - most often layers that are loosely coupled, for example through web-services or JMS. DTOs can also be used in views, so that the web-layer gets objects that it can use to display to the user and these are different from the entities, in order to avoid entity state management problems and mapping mess.
DTO 背后的一般思想是,它们用于跨架构层传输数据 - 通常是松散耦合的层,例如通过 Web 服务或 JMS。DTO 也可以用在视图中,这样 web 层会得到可以用来显示给用户的对象,这些对象与实体不同,以避免实体状态管理问题和映射混乱。
But for the typical application I would argue that DTOs are unnecessary. Use your entities in your JSF beans and views, just be careful with a possible LazyInitializationException
. My experiences shows that entities can be used as DTOs (without the need of a new class) in most of the cases, with slightly more care. And wherever I've seen DTOs in smaller projects, they only complicated things unnecessarily.
但是对于典型的应用程序,我认为 DTO 是不必要的。在 JSF bean 和视图中使用您的实体,只需小心可能的LazyInitializationException
. 我的经验表明,在大多数情况下,实体可以用作 DTO(不需要新类),但要多加小心。无论我在哪里看到 DTO 在较小的项目中,它们只会使事情变得不必要地复杂化。