2013-05-07 127 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