Projection 是指 select 時只回傳指定欄位,在 Spring Data 中有幾種情境。
假設有個 Entity 為:
使用 JPARepository
提供的 findByXXX
method,這時我們可以用 projection class 並把我們想指定的回傳欄位寫在 constructor 中,如:
這時我們的 Repository 為:
執行的 SQL 為:
可以看到產生的 SQL 只有 select Name 和 CreateTime 兩個欄位。
另一個方式是提供 projection interface 其中有我們想要的欄位的 getter,比方我們的 TestDTO
可以改成:
Repository 可以不用修改,這時執行的 SQL 一樣只會查詢 Name 和 CreateTime:
projection interface 還可以動態地組合欄位, 比方我們的 TestDTO
想要把 name
和 createTime
合成 createInfo
,我們可以用 @Value
來達成:
這樣查詢出來的 TestDTO
呼叫 getCreateInfo
時的值會是:
test 2021-01-13 14:03:37.07
另一種情況是有用 @Query
提供執行的 SQL,若 @Query
中是 HQL 這時我們可以有下面幾種做法:
@Query
中 new
該 projection class,例如:
執行的 SQL:
@Query
中的欄位要給予別名,而 projection interface 的 getter 名稱則要符合別名,注意這邊別名時是使用駝峰式命名,比方我們的 Repository 為:
所以我們的 projection interface 為:
這時執行的 SQL 為:
Map<String, Object>
,同時要給予欄位別名,這個別名變成回傳 Map
的 key 比方:
這時執行的 SQL 為:
但我們就必須用別名當 key 來取值
Object[][]
比方:
這時執行的 SQL 為:
但我們就必須用陣列 index 順序來取值取值
如果 @Query
中是原生 SQL,也就是有加上 native=true
比方:
這時就無法用 projection class 在 SQL 中 new
,但下面幾種做法依然可以使用:
Map<String, Object>
的做法Object[][]
的做法參考來源: