70

我最近了解到,可以在JPQL语句中创建新对象,如下所示:

select new Family(mother, mate, offspr)
from DomesticCat as mother
    join mother.mate as mate
    left join mother.kittens as offspr

这是要避免还是要接受的事情?根据良好实践,何时使用此功能是合理的?

4

3 回答 3

136

不要回避它,SELECT NEW 就在那里,因为它有完全有效的用例,正如§10.2.7.2 中所提醒的那样。EJB 3.0 JPA 规范的 SELECT 子句中的JPQL 构造函数表达式

可以在 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

简而言之,当您不想以类型安全的方式(而不是Object[])检索完整实体或对象的完整图时,请使用 SELECT NEW 。将查询结果映射到实体类还是非映射类将取决于您的选择。一个典型的例子是列表屏幕(您可能不需要所有详细信息)。

换句话说,不要到处使用它,但不要禁止使用它(很少有东西只有黑色或白色)。

于 2010-03-01T21:31:33.697 回答
31

当您想要检索数据传输对象时,您经常使用这种查询。也许报告可能是使用它的好地方。如果您只想检索单个域对象(例如从 Family代替),那么没有理由使用它。

于 2010-03-01T16:22:20.883 回答
7

使用 new 创建的 Object 不必是 DTO,即将由业务层导出的 Object。它也可以是 POJO 域对象,即业务层内部使用的对象。

将这种 POJO 用作部分对象而不是完整的 JPA 实体的原因是在特定类型的 JOINS 中的性能。解释这一点的一个很好的资源是:http ://use-the-index-luke.com/sql/join/hash-join-partial-objects

于 2015-04-04T09:34:08.020 回答