Java JPQL 在 Select 语句中创建新对象 - 避免还是拥抱?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2355728/
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
JPQL Create new Object In Select Statement - avoid or embrace?
提问by mgamer
I've learnt recently that it is possible to create new Objects in JPQL
statements as follows:
我最近了解到可以在JPQL
语句中创建新对象,如下所示:
select new Family(mother, mate, offspr)
from DomesticCat as mother
join mother.mate as mate
left join mother.kittens as offspr
Is this something to be avoided or rather to embrace? When is usage of this feature justified in the light of good practices?
这是应该避免的还是应该接受的?根据良好实践,何时使用此功能是合理的?
采纳答案by Pascal Thivent
Don't avoid it, the SELECT NEW is there because there are perfectly valid use cases for it as reminded in the §10.2.7.2. JPQL Constructor Expressions in the SELECT Clauseof the EJB 3.0 JPA Specification:
不要避免它,SELECT NEW 就在那里,因为正如§10.2.7.2 中所提醒的那样,它有完全有效的用例。EJB 3.0 JPA 规范的 SELECT 子句中的JPQL 构造函数表达式:
A constructor may be used in the SELECT list to return one or more Java instances. The specified class is not required to be an entity or to be mapped to the database. The constructor name must be fully qualified.
If an entity class name is specified in the SELECT NEW clause, the resulting entity instances are in the new state.
SELECT NEW com.acme.example.CustomerDetails(c.id, c.status, o.count) FROM Customer c JOIN c.orders o WHERE o.count > 100
可以在 SELECT 列表中使用构造函数来返回一个或多个 Java 实例。指定的类不需要是实体或映射到数据库。构造函数名称必须是完全限定的。
如果在 SELECT NEW 子句中指定了实体类名称,则生成的实体实例处于新状态。
SELECT NEW com.acme.example.CustomerDetails(c.id, c.status, o.count) FROM Customer c JOIN c.orders o WHERE o.count > 100
In short, use the SELECT NEW when you don't want to retrieve a full entity or a full graph of objects in a type safe way (as opposed to an Object[]
). Whether you map the result of a query in an entity class or a non mapped class will depend on your select. A typical example would be a list screen (where you might not want all the details).
简而言之,当您不想以类型安全的方式(而不是Object[]
)检索完整实体或完整对象图时,请使用 SELECT NEW 。您是在实体类中映射查询结果还是在非映射类中映射查询结果将取决于您的选择。一个典型的例子是列表屏幕(您可能不需要所有详细信息)。
In other words, don't use it everywhere but don't forbid its use (few things are only black or white).
换句话说,不要到处使用它,但不要禁止它的使用(很少有东西只有黑色或白色)。
回答by Arthur Ronald
You often use this sort of query when you want to retrieve a Data Transfer Object. Maybe a report can be a good place to use it. If you just want to retrieve a single domain object (like from Familyinstead), so there is no reason to use it.
当您想要检索数据传输对象时,您经常使用这种查询。也许报告可以是使用它的好地方。如果您只想检索单个域对象(例如从 Family 中取而代之),那么没有理由使用它。
回答by gmournos
An Object created with new does not have to be a DTO, i.e. an Object which will be exported by the Business layer. It can also be a POJO Domain Object, i.e. an Object used internally by the Business layer.
使用 new 创建的对象不一定是 DTO,即将由业务层导出的对象。它也可以是 POJO 域对象,即业务层内部使用的对象。
The reason to use this kind of POJOs as a partial Object instead of the full JPA Entity is performance in specific kinds of JOINS. A great resource which explains this is: http://use-the-index-luke.com/sql/join/hash-join-partial-objects
使用这种 POJO 作为部分对象而不是完整的 JPA 实体的原因是在特定类型的 JOINS 中的性能。解释这一点的一个很好的资源是:http: //use-the-index-luke.com/sql/join/hash-join-partial-objects