2013-05-07 122 views
31

我在我的项目中使用弹簧数据JPA。我正在玩数百万条记录。我有一个要求,我必须为各种表获取数据并构建一个对象,然后在UI上绘制它。现在如何实现这个我的Spring数据仓库。我已经读过,它可以通过命名本机查询来实现。Spring Data JPA:Query如何返回非实体对象或对象列表?

如果命名原生查询没有返回一个实体或实体 的列表,我们可以将查询结果通过 使用@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") 

在上面的例子中,我只是想从学生的实体结果到另一个POJO“CustomStudent”,这是不是一个实体。 (这个例子我试图执行只是为了POC目的,实际用例是非常复杂的,复杂的查询返回的结果集不同)。

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

+0

我遇到了同样的问题来到最近并很高兴看到有人发帖,并得到了一个解决方案,它呢! – 2017-06-17 02:53:18

回答

23

我深感惊讶,当我来到这个防空火炮的第一次,但是,是的,你可以使用@SqlResultSetMapping只标量和管理的实体地图查询结果。

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

另一种方法是使用@MappedSuperclass。在@SqlResultSetMapping中使用表示为@MappedSuperclass(您的案例中的CustomStudent)的类可以(不确定是100%)。但您需要引入继承层次结构,即您的学生实体必须扩展CustomStudent。这将吸大部分从正确的面向对象设计的时候,因为继承是有点做作......

+0

你的意思是原始类型? – Alex78191 2017-05-26 13:57:57

+1

你可以使用ConstructorResult https://stackoverflow.com/a/42942353/4854931 – Alex78191 2017-05-26 14:00:48

21

你可以做那么MyDto对象将只需要一个构造函数中定义类似

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

用正确的领域,即

public MyDto(String id, String otherProperty) { this.id = id; this.otherProperty = otherProperty; } 
+0

我可以写一些像'SELECT new path.to.dto.MyDto(e.id,new path.to.dto.OtherDto)' – masSdev 2017-02-25 05:32:15

+0

不,但在MyDto中,您可以拥有一个OtherDto属性,而在MyDto的构造函数中,您可以使用传递给MyDto构造函数的数据来设置OtherDto属性。或者你可以使用@SqlResultSetMapping注解。 – tlavarea 2017-03-04 16:01:29

+0

当我写这篇文章时,编译失败,'验证失败的查询方法公共抽象..' – 2017-07-18 15:27:59

17

如何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") 
+0

你好,这听起来不错,但NamedQuery仍然必须附加到和实体成为持久性单元的一部分? – romainbsl 2018-02-01 09:38:42