SpEL support in Spring Data JPA @Query definitions
来源:互联网 发布:qq旋风mac 迅雷下载 编辑:程序博客网 时间:2024/05/23 15:41
https://spring.io/blog/2014/07/15/spel-support-in-spring-data-jpa-query-definitions
Spring Data JPA allows manually defining the query to be executed by a repository method using the @Query
annotation. Unfortunately parameter binding in JPQL is quite limited only allowing you to set a value and providing some type conversion. The latest Spring Data JPA M1release of the Evans release train eases this pain by adding support
for using SpEL expressions to use dynamically bound parameters within statements in @Query
annotations which provides additional flexibility when defining queries manually. In this blog post, I am going to introduce you to the capabilities of this feature.
Method parameter expressions
SpEL support provides access to the query method arguments. This allows you to either simply bind the parameter as is or perform additional operations before binding.
@Query("select u from User u where u.age = ?#{[0]}")List<User> findUsersByAge(int age);@Query("select u from User u where u.firstname = :#{#customer.firstname}")List<User> findUsersByCustomersFirstname(@Param("customer") Customer customer);
Parameters are exposed for indexed access ([0]
in the first method) or via the name declared using @Param
. The actual SpEL expression binding is either triggered by ?#
or :#
. We support both types to allow you to be consistent to standard JPQL parameter bindings that also might occur in the query definition.
Parameters of special types like Sort
and `Pageable
are exposed with their simple class names as variables.
Advanced SpEL expressions
While advanced parameter binding is a very useful feature, the real power of SpEL stems from the fact, that the expressions can refer to framework abstractions or other application components. A very common scenario for SpEL is the definition of security constraints. So it would be cool if we could restrict a query to only return results related to the currently authenticated user:
@Query("select u from User u where u.emailAddress = ?#{principal.emailAddress}")List<User> findCurrentUserWithCustomQuery();
As you can see we refer to a property of Spring Security’s principal
. So how does the Spring Data SpEL support integrate with Spring Security.
SpEL EvaluationContext extension model
Spring Data exposes an extension point EvaluationContextExtension
. The interface allows implementors to customize the EvaluationContext
in a very detailed way but for convenience, we provide a EvaluationContextExtensionSupport
base class to conveniently let you only implement the parts you’re interested in:
class SecurityEvaluationContextExtension extends EvaluationContextExtensionSupport { @Override public String getExtensionId() { return "security"; } @Override public SecurityExpressionRoot getRootObject() { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); return new SecurityExpressionRoot(authentication) {}; }}
For our Spring Security extension we extend EvaluationContextExtensionSupport
and override the getRootObject()
method and return a new SecurityExpressionRoot
instance which exposes all the security properties and expressions you already know from usage in @PreAuthorize
. This step also makes them available in SpEL expressions in our @Query
annotation.
The final step we need to take is to register the security extension as a bean:
@Configuration@EnableJpaRepositoriesclass SecurityConfiguration { @Bean EvaluationContextExtension securityExtension() { return new SecurityEvaluationContextExtension(); }}
Spring Data JPA will pick up all beans of type EvaluationContextExtension
and use those to prepare the EvaluationContext
to be used to evaluate the SpEL expression defined in @Query
.
The extension in place will now let you leverage the full power of the Spring Security SpEL functions. Imagine a repository query method that shall return the BusinessObject
s which the current user is owner of or all BusinessObject
s if the current user is admin. The query method definition would look like this:
interface SecureBusinessObjectRepository extends Repository<BusinessObject,Long>{ @Query("select o from BusinessObject o where o.owner.emailAddress like "+ "?#{hasRole('ROLE_ADMIN') ? '%' : principal.emailAddress}") List<BusinessObject> findBusinessObjectsForCurrentUser();}
You can find the working examples of the snippets seen here in the Spring-Data-Examplesrepository.
- SpEL support in Spring Data JPA @Query definitions
- Spring Data JPA @Query
- Spring Data jpa @query 关于IN关键字查询
- Spring Data JPA Using @Query
- jpa Query查询,时间查询,in查询(Spring Data Jpa 3)
- Spring Data JPA 常用注解 @Query、@NamedQuery
- spring DATA (jpa) @query 和JdbcTemplate
- spring data jpa 利用@Query进行查询
- Spring data jpa 之 Query注解
- @Query注解的用法(Spring Data JPA)
- @Query注解的用法(Spring Data JPA)
- @Query注解的用法(Spring Data JPA)
- Spring Data JPA进阶-@Query注解
- @Query注解的用法(Spring Data JPA)
- spring data jpa 利用@Query进行查询
- @Query注解的用法(Spring Data JPA)
- 【Spring-data-jpa】利用@query组合查询
- Spring Data Jpa @Query Pageable用法
- sizeof 是关键字不是函数
- java学习笔记五
- 基于CANoe的ECU Bootloader刷写软件
- Scrapy-spiders(爬虫)
- 蓝桥杯 2n皇后问题
- SpEL support in Spring Data JPA @Query definitions
- BZOJ 3629 [JLOI2014] 聪明的燕姿 dfs
- python paramiko 验证
- 关于JS在页面替换字符串的操作的注意点
- javascript基础3.0
- 整数快速幂——次方求模
- new/delete与malloc/free的异同
- 基于display:table的CSS布局
- IDEA中创建spring boot 步骤,配置及模态窗口操作