Spring Data内建的查询构造机制可能是最有特色的一个地方。
Spring Data会识别出find...By
, read...By
和get...By
这样的前缀,从后面的命名中解析出查询的条件。方法命名的的第一个By
表示查询条件的开始,多个条件可以通过And
和Or
来连接。
public interface UserRepository extends Repository<User, Long> {
List<User> findByEmailAndName(String email, String name);
// 使用DISTINCT标识
List<User> findDistinctUserByNameOrEmail(String name, String email);
List<User> findUserDistinctByNameOrEmail(String name, String email);
// 忽略email字段的大小写
List<User> findByEmailIgnoreCase(String email);
// 忽略所有字段的大小写
List<User> findByNameAndEmailAllIgnoreCase(String name, String email);
// 使用ORDERBY
List<User> findByNameOrderByIdAsc(String name);
List<User> findByEmailOrderByNameDesc(String name);
}
除了And
和Or
,表示查询条件的属性表达式中还可以通过Between
、LessThan
、GreaterThan
和Like
等操作符。
可以使用IngoreCase
来忽略属性的大小写,也可以使用AllIgnoreCase
来忽略全部属性的大小写。
可以使用OrderBy
来进行排序查询,排序的方向是Asc
跟Desc
。
注意有些操作符是和特定数据库相关的,使用时应该确保数据库能够支持。
Spring Data为我们提供了以下关键字的支持,我们可以根据自己的需求,选择一个或者多个关键字来构建我们的查询方法:
关键字 | 例子 | 对应的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 |
… where x.age in ?1 |
NotIn | findByAgeNotIn(Collection |
… 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) |
其中,对于In
和NotIn
关键字来说,他们对应的参数可以是Collection
,也可以是Array
,还可以是可变参数。
Spring Data还支持内嵌类的属性表达式。
为了举例,假设User
类包含firstName
属性,则通过firstName
属性来查询对应Blog
,可以这样写:
假设类Blog
包含一个Address
,Address
类中有 ZipCode
属性。下面的方法可以根据ZipCode
来查询对应的User。
Spring Data按照如下方式解析方法命名:
AuthorFirstName
作为一个整体,检查Blog
对象中是否包含有这个属性;
如果包含则解析成功;否则按照驼峰命名格式从有右到左解析出头部和尾部,在这个例子中分别对应于AuthorFirst
和Name
,如果头部部分对应于某个属性,则继续处理尾部。
否则会将分割点左移,继续处理。左移之后对应的头部和尾部分别为Author
和FirstName
。此时得到了正确的匹配。
为了提高解析效率,可以通过下划线_
来区分,比如:
但是一般情况下不建议使用,应该符合标准的Java命名规范。
登录发表评论 登录 注册