【问题标题】:Static Factory Method in JPQL query instead of constructorJPQL 查询中的静态工厂方法而不是构造函数
【发布时间】:2018-08-04 05:28:30
【问题描述】:

目前我使用很多查询,它们使用构造函数在 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 中可行吗?

【问题讨论】:

    标签: java spring hibernate jpa jpql


    【解决方案1】:

    您可以使用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);
    

    【讨论】:

    • 如果我有 4 个字段,是否需要为这些字段的各种组合创建不同的接口?那么在这种情况下有 2^4 个接口?
    • 在上面的例子中,我为用户实体中可用的两个字段创建了一个接口
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-28
    • 2014-02-18
    • 1970-01-01
    • 1970-01-01
    • 2013-07-24
    • 1970-01-01
    相关资源
    最近更新 更多