Spring数据查询方法
在本文中,我们将了解如何在Spring Data中为存储库接口方法生成查询,以及在Spring Data中针对查询方法的所有选项。
定义查询方法
在Spring Data Repository代理中,有两种方法可从方法名称派生持久存储特定的查询:
通过直接从方法名称派生查询。
通过使用手动定义的查询。
可用选项还取决于所使用的持久性存储。
Spring数据中的查询查找策略
以下策略可用于存储库基础结构来解决查询。使用XML配置,我们可以通过query-lookup-strategy属性在名称空间中配置策略。对于Java配置,可以使用Enable $ {store} Repositories注释的queryLookupStrategy属性。
可以使用具有以下值的Enum QueryLookupStrategy.Key访问可用的查询查找策略:
创建-如果使用此选项,则Spring框架尝试根据查询方法名称自动构造查询。
USE_DECLARED_QUERY –对于此选项,Spring框架尝试查找声明的查询。该查询可以由@NamedQuery(与Spring Data JPA结合使用)或者@Query之类的注释定义。
CREATE_IF_NOT_FOUND –这是默认选项,它结合了CREATE和USE_DECLARED_QUERY。它首先查找一个声明的查询,如果找不到声明的查询,它将创建一个基于名称的自定义方法查询。
使用带有@EnableJpaRepositories注释的queryLookupStrategy属性的示例。
@Configuration @EnableJpaRepositories(basePackages = "com.theitroad.springproject.dao", queryLookupStrategy=Key.CREATE) @EnableTransactionManagement @PropertySource("classpath:config/db.properties") public class JPAConfig { ... ... }
在Spring Data中创建查询
通过扩展Spring Data的Repository接口(如CrudRepository,JpaRepository,ReactiveCrudRepository),我们可以直接访问一组CRUD操作(即保存,saveAll,findById,findAll,findAllById,计数,删除,deleteById等)。我们还可以添加自定义查询方法,如EmployeeRepository的以下定义中所给。
public interface EmployeeRepository extends CrudRepository<Employee, Integer> { List<Employee> findByLastName(String lastName); }
当Spring Data看到扩展其Repository标记接口的接口时,查询执行引擎会在运行时为这些接口创建代理实例。它扫描每个方法,并解析其方法签名。解析机制从方法中剥离前缀find ... By,Read ... By,query ... By,count ... By,get ... By,然后开始解析其余部分。
例如,在没有自定义方法findByLastName的情况下,看到findBy将解析该方法的其余部分,并开始在域类(Employee)中寻找相同的属性名称。因为它可以看到Employee具有lastName属性,所以它现在具有足够的信息来知道如何为该特定方法创建查询。
方法名称可能包含其他表达式,例如Distinct,用于在要创建的查询上设置不同的标志。但是,方法名称中的第一个" By"用作分隔符,以指示实际标准的开始。
下表描述了JPA支持的关键字以及包含该关键字的方法所转换的含义:
关键字 | 示例 | JPQL代码段 |
---|---|---|
And | findByLastnameAndFirstname | … where x.lastname = ?1 and x.firstname = ?2 |
Or | findByLastnameOrFirstname | … where x.lastname = ?1 or x.firstname = ?2 |
Is,Equals | findByFirstname, findByFirstnameIs, findByFirstnameEquals | … where x.firstname = ?1 |
Between | findByStartDateBetween | … where x.startDate between ?1 and ?2 |
LessThan | findByAgeLessThan | … where x.age < ?1 |
LessThanEqual | findByAgeLessThanEqual | … where x.age <= ?1 |
GreaterThan | findByAgeGreaterThan | … where x.age > ?1 |
GreaterThanEqual | findByAgeGreaterThanEqual | … where x.age >= ?1 |
After | findByStartDateAfter | … where x.startDate > ?1 |
Before | findByStartDateBefore | … where x.startDate < ?1 |
IsNull | findByAgeIsNull | … where x.age is null |
IsNotNull,NotNull | findByAge(Is)NotNull | … where x.age not null |
Like | findByFirstnameLike | … where x.firstname like ?1 |
NotLike | findByFirstnameNotLike | … where x.firstname not like ?1 |
StartingWith | findByFirstnameStartingWith | … where x.firstname like ?1 (parameter bound with appended %) |
EndingWith | findByFirstnameEndingWith | … where x.firstname like ?1 (parameter bound with prepended %) |
Containing | findByFirstnameContaining | … where x.firstname like ?1 (parameter bound wrapped in %) |
OrderBy | findByAgeOrderByLastnameDesc | … where x.age = ?1 order by x.lastname desc |
Not | findByLastnameNot | … where x.lastname <> ?1 |
In | findByAgeIn(Collection<Age> ages) | … where x.age in ?1 |
NotIn | findByAgeNotIn(Collection<Age> ages) | … where x.age not in ?1 |
True | findByActiveTrue() | … where x.active = true |
False | findByActiveFalse() | … where x.active = false |
IgnoreCase | findByFirstnameIgnoreCase | … where UPPER(x.firstame) = UPPER(?1) |
这些运算符中的许多运算符都可以与其他受支持的持久性存储(例如MongoDB,Apache Cassandra)一起使用,但是请务必查看特定的参考指南。
在Spring数据中声明查询
要声明查询,可以在Spring Data JPA的情况下使用@NamedQuery注释。这些配置元素的查询必须使用JPA查询语言进行定义。
在这里查看使用@NamedQuery Annotation的Spring Data JPA示例SpringData JPA @NamedQuery Annotation示例
我们还可以在Repository界面中使用@Query注释查询方法。对于Spring Data JPA,Spring Data JDBC,Spring Data MongoDB,Spring Data Neo4J @Query注释可用于定义查询。确保检查特定的参考指南。
Spring Data JDBC模块仅支持使用@Query注释手动定义查询。当前不支持从方法名称中查询。