java - JPQL 查询中的静态工厂方法而不是构造函数

标签 java spring hibernate jpa jpql

目前我使用了很多查询,这些查询使用构造函数在 JPQL 中构建值对象,如下所示

@Query("SELECT new com.DocDTO(d.documentId, d.docType) FROM Document d where d.parentId=:parentId")
Set<DocDTO> getDocsWithinFolder(@Param("parentId") Long parentId);

但是随着代码变得复杂,我需要使用构造函数参数的各种组合来构建对象,从而导致经典的伸缩问题。

Effective Java (Item1) 中所述,有没有一种方法可以通过传递工厂方法而不是构造函数来构建 JPQL 查询?我在想

  @Query("SELECT DocDTO.query1(d.documentId, d.docType) FROM Document d where d.parentId=:parentId")
    Set<DocDTO> getDocsWithinFolder(@Param("parentId") Long parentId);

然后在 DocDTO 类中构建适当的静态工厂方法 query1。这在 JPQL 中可能吗?

最佳答案

您可以使用动态投影 来解决这个问题。动态投影让您可以动态更改单个查询的返回类型。为了更好地理解这一点,让我们举一个这个用户实体的例子:

    @Entity
    public class User {
        @Id
        @GeneratedValue(strategy=GenerationType.AUTO)
        private Long id;
        private String firstName;
        private String lastName;
        private String email;
        // setter and getters
}

如果您只想首先使用动态投影获取用户的姓名,您需要创建一个如下所示的界面:

public interface Name {
      String getLastName();
      String getFirstName();
}

在您的存储库中,您需要创建如下查询:

<T> List<T> findByLastName(String lastName, Class<T> type);

或使用@Query

@Query("select u.firstName,u.lastName from User u where lastName=?1")
<T> List<T> findByLastName(String lastName,Class<T> type);

在您的服务中:

List<Name> name = findByLastName("xyz",Name.class);

关于java - JPQL 查询中的静态工厂方法而不是构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48960020/

相关文章:

java - 依赖于多个子类实例的实例创建模式

Java Web应用程序安全理念

java - 分页对垃圾回收有什么影响?

java - Maven/ Spring /Java : ClassNotFoundException - but I know class is there

java - 如何组织 Spring Integration 重试方法,其列表随着每次重试而减少?

java - spring boot通过schema.sql导入程序

HibernatePersistence 类未发现 JPA + Hibernate + OSGI 的异常

mysql - Hibernate - 在表的所有列中搜索文本

java - org.dom4j.DocumentException : Stream closed Nested exception: Stream closed

java - 是否需要在每次查询时关闭实体管理器?