Spring Data JPA:Query如何返回非实体对象或对象列表?

DHR*_*SAL 33 java hibernate java-ee jpa-2.0 spring-data-jpa

我在我的项目中使用spring数据JPA.我正在玩数百万条记录.我有一个要求,我必须获取各种表的数据并构建一个对象,然后在UI上绘制它.现在如何实现我的Spring数据存储库.我已经读过它可以通过命名本机查询来实现.

如果命名的本机查询未返回实体或实体列表,则可以使用@SqlResultSetMapping批注将查询结果映射到正确的返回类型.

但是,当我尝试使用@SqlResultSetMapping它时,正在采取另一个entityResult.意思是我理解的是它只是将一些查询结果转换为实体结果集,但我想要一个非实体对象的结果集.

@SqlResultSetMapping(
    name="studentPercentile",
    entities={
        @EntityResult(
           entityClass=CustomStudent.class,
              fields={
                  @FieldResult(name="id", column="ID"),
                  @FieldResult(name="firstName", column="FIRST_NAME"),
                   @FieldResult(name="lastName", column="LAST_NAME")
              }         
        )
   }
) 
@NamedNativeQuery(
    name="findStudentPercentile", 
    query="SELECT * FROM STUDENT", 
    resultSetMapping="studentPercentile")
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,我只是试图将学生实体的结果转化为另一个不是实体的pojo'CustomStudent '.(这个例子我试图只为POC目的执行,实际的用例很复杂,复杂的查询返回不同的结果集).

如何实现上述用例?除了使用名称查询之外还有其他方法我的存储库方法返回非实体对象吗?

Pio*_*ski 24

当我第一次遇到这个问题时,我感到非常惊讶,但是,是的,您可以使用@SqlResultSetMapping将查询结果映射到标量和管理实体.

我想,你能做的最好就是跳过自动映射.没有映射的查询将返回List<Object[]>,您可以按照需要进行映射.

另一种方法是使用@MappedSuperclass.表示为@MappedSuperclass(在您的情况下为CustomStudent)的类可以(但不确定100%)在@SqlResultSetMapping中使用.但是您需要引入继承层次结构,即您的Student实体必须扩展CustomStudent.这大部分时间都会从适当的OO设计中吸取,因为继承会有点人为......


tla*_*rea 24

你可以做点什么

@NamedQuery(name="findWhatever", query="SELECT new path.to.dto.MyDto(e.id, e.otherProperty) FROM Student e WHERE e.id = ?1")
Run Code Online (Sandbox Code Playgroud)

那么MyDto对象只需要一个用正确的字段定义的构造函数即

public MyDto(String id, String otherProperty) { this.id = id; this.otherProperty = otherProperty; }
Run Code Online (Sandbox Code Playgroud)

  • 我可以写类似`SELECT new path.to.dto.MyDto(e.id, new path.to.dto.OtherDto)` (2认同)

Dai*_*mon 18

JPA 2.1 ConstructorResult怎么样?

@SqlResultSetMapping(
    name="studentPercentile",
    classes={
        @ConstructorResult(
            targetClass=CustomStudent.class,
            columns={
                @ColumnResult(name="ID"),
                @ColumnResult(name="FIRST_NAME"),
                @ColumnResult(name="LAST_NAME")
            }
        )
    }
)

@NamedNativeQuery(name="findStudentPercentile", query="SELECT * FROM STUDENT", resultSetMapping="studentPercentile")
Run Code Online (Sandbox Code Playgroud)

  • 您好,这听起来不错,但是 NamedQuery 仍然必须附加到 Entity 才能成为持久性单元的一部分? (2认同)