领先一步
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