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

时间:2018-02-24 06:25:36

标签: 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中是否可行?

1 个答案:

答案 0 :(得分:3)

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

    @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);