領先一步
VMware 提供培訓和認證,助您加速進步。
瞭解更多有時,無論您嘗試應用多少功能,似乎都無法讓 Spring Data JPA 在查詢傳送到 EntityManager 之前應用所有您想要的東西。
使用 3.0.0-SNAPSHOT(並作為 Spring Data 下一個里程碑釋出列車的目標),您現在可以在查詢傳送到 EntityManager 之前獲取查詢並“重寫”它。也就是說,您可以在最後一刻進行任何更改。
請看下面
示例 1. 使用 @Query 宣告 QueryRewriter
public interface MyRepository extends JpaRepository<User, Long> {
@Query(value = "select original_user_alias.* from SD_USER original_user_alias",
nativeQuery = true, queryRewriter = MyQueryRewriter.class) // (1)
List<User> findByNativeQuery(String param);
@Query(value = "select original_user_alias from User original_user_alias",
queryRewriter = MyQueryRewriter.class) // (2)
List<User> findByNonNativeQuery(String param);
}
這個純 SQL 查詢(感謝 nativeQuery)在呼叫之前將透過尚未定義的 MyQueryRewriter 進行路由。
這個 JPQL 查詢在交給 EntityManager 之前,也將透過相同的 MyQueryRewriter 進行路由。
然後,您可以自己編寫您的查詢重寫器,如下所示!
示例 2. 示例 QueryRewriter
public class MyQueryRewriter implements QueryRewriter {
@Override
public String rewrite(String query, Sort sort) {
return query.replaceAll("original_user_alias", "rewritten_user_alias");
}
}
好的,這個例子有點牽強。我們基本上只是改變了一個特定查詢別名的名稱。但你真的可以做任何你能想到的事情。這個鉤子讓你有機會改變一點(或很多!)。
只需確保在應用程式上下文中註冊一個 MyQueryRewriter 例項。無論您使用 Spring Framework 的基於 @Component 的註解,還是透過 @Configuration 類中的 @Bean 方法提供它,選擇權都在您。
警告
您的 QueryRewriter 在 Spring Data JPA 執行完所有檢查後被呼叫。您負責向 EntityManager 提供一個有效的查詢。
但是等等……還有更多!
雖然您可以將 QueryRewriter 編寫為一個獨立的 bean,但也可以將其直接放在使用它的倉庫中!
示例 3. 提供 QueryRewriter 的倉庫
public interface MyRepository extends JpaRepository<User, Long>,
QueryRewriter { // (1)
@Query(value = "select original_user_alias.* from SD_USER original_user_alias",
nativeQuery = true, queryRewriter = MyRepository.class) // (2)
List<User> findByNativeQuery(String param);
@Query(value = "select original_user_alias from User original_user_alias",
queryRewriter = MyRepository.class) // (3)
List<User> findByNonNativeQuery(String param);
@Override
default String rewrite(String query, Sort sort) { // (4)
return query.replaceAll("original_user_alias", "rewritten_user_alias");
}
}
讓您的倉庫介面繼承 QueryRewriter 介面。
將您的倉庫名稱插入到原生查詢的 @Query.queryRewriter 條目中。
將您的倉庫名稱插入到 JPQL 查詢的 @Query.queryRewriter 條目中。
覆蓋 rewrite(String,Sort) 方法並插入一個 default 值,然後 POOF,您就完成了!
溫馨提示:根據您具體要做的事情,您可能需要不止一個重寫器。
Spring Data JPA 不僅支援 Spring 的應用程式上下文,還支援基於 CDI 的環境。
愉快地查詢吧!
-Greg Turnquist