Spring JPA之find拓展方法示例详解
前言
前两篇我们详细了解了 findById 和 findAll 以及 findAll 的分页查询,如果说JPA只有上面的两种查询功能,那就太low了,今天让我们再深入的去探究一下其他查询方法。
一、单条件查询
类似 select * from * where 条件
的查询
1、精确查询(确定值,例如:=、is)
Dao 层(因为已经不是自带方法了,所以需要在Dao添加接口)
User findByName(String name);
控制台打印如下:
Hibernate:
select
user0_.id as id1_0_,
user0_.age as age2_0_,
user0_.name as name3_0_
from
user user0_
where
user0_.name=?
2、范围查询(一定范围,例如<、<=、>、>=、in、between)
a)运算符
Dao 层
List<User> findByAgeLessThan(int age);
List<User> findByAgeLessThanEqual(int age);
控制台打印如下:
Hibernate:
select
user0_.id as id1_0_,
user0_.age as age2_0_,
user0_.name as name3_0_
from
user user0_
where
user0_.age<?
Hibernate:
select
user0_.id as id1_0_,
user0_.age as age2_0_,
user0_.name as name3_0_
from
user user0_
where
user0_.age<=?
其他的“>”就是findByAgeGreaterThan
,“>=”就是findByAgeGreaterThanEqual
等等
b)between
Dao 层
List<User> findByAgeBetween(int ageLeft,int ageRight);
控制台打印如下:
Hibernate:
select
user0_.id as id1_0_,
user0_.age as age2_0_,
user0_.name as name3_0_
from
user user0_
where
user0_.age between ? and ?
c)in
Dao 层
List<User> findByAgeIn(int[] ages);
控制台打印如下:
Hibernate:
select
user0_.id as id1_0_,
user0_.age as age2_0_,
user0_.name as name3_0_
from
user user0_
where
user0_.age in (
? , ?
)
findByAgeNotIn
的查询跟in结果是相对的,但是用法是一样的,传入的参数也是数组
3、模糊查询
模糊查询无非就是 like 语句,这里我们就不详细讨论 like 如何使用了,只介绍一下 JPA 中的 like 如何去实现。
以下是Dao 层的like实现的各接口:
public List<User> findByNameLike(String name){
return userDao.findByNameLike(name);
}
public List<User> findByNameStartingWith(String name){
return userDao.findByNameStartingWith(name);
}
public List<User> findByNameStartsWith(String name){
return userDao.findByNameStartsWith(name);
}
public List<User> findByNameEndingWith(String name){
return userDao.findByNameEndingWith(name);
}
public List<User> findByNameContaining(String name){
return userDao.findByNameContaining(name);
}
上面虽然有5个不同的接口,但是控制台打印却是一致的,如下:
Hibernate:
select
user0_.id as id1_0_,
user0_.age as age2_0_,
user0_.name as name3_0_
from
user user0_
where
user0_.name like ? escape ?
那他们5个具体有啥区别呢?不急,我们详细看看:
a)findByNameLike
请求url findByNameLike?name=aa
,控制台打印入参如下:
binding parameter [1] as [VARCHAR] - [aa]
从输入值可以看出,单独的like你传什么就将什么放在like后面;如果传的是纯字符,则相当于精确查询;如果你加上“%”,那就可以进行模糊查询了:findByNameLike?name=%25aa
(url中的“%”转义为“%25”),控制台打印入参如下:
binding parameter [1] as [VARCHAR] - [%aa]
b)findByNameStartingWith
请求urlfindByNameStartingWith?name=aa
,控制台打印入参如下:
binding parameter [1] as [VARCHAR] - [aa%]
从输入值来看,这个就是获取以“aa”开头的所有数据,其实从名字也可以看出来他的实际作用。后面的findByNameStartsWith
跟这个的作用是一样的。
以此类推:findByNameEndingWith(aa)
、findByNameEndsWith(aa)
: 输入值应为 [%aa],就是获取以“aa”为结尾的所有数据;findByNameContaining(aa)
:输入值应为 [%aa%]\,就是获取任意位置包含“aa”的数据。
二、多条件查询
类似select* from * where 条件1 and 条件2
Dao 层
User findByNameAndAge(String name, int age);
控制台打印如下:
Hibernate:
select
user0_.id as id1_0_,
user0_.age as age2_0_,
user0_.name as name3_0_
from
user user0_
where
user0_.name=?
and user0_.age=?
多条件查询其实就是多个单条件查询所叠加的效果;主要使用 and 来表示同时满足多个条件的结果,而 or 用于表示满足其中一个条件的结果。
三、关键字
以下是整理的JPA支持的关键字,大家可以自行取之。
关键字 | 示例 | JPQL片段 |
---|---|---|
And | findByNameAndAge | ... where x.name = ?1 and x.age = ?2 |
Or | findByNameOrAge | ... where x.name = ?1 or x.age = ?2 |
Is,Equals | findByName,findByNameIs,findByNameEquals | ... where x.name = ?1 |
Between | findByAgeBetween | ... where x.age 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 | findByAgeAfter | ... where x.age > ?1 |
Before | findByAgeBefore | ... where x.age< ?1 |
IsNull | findByAgeIsNull | ... where x.age is null |
IsNotNull,NotNull | findByAge(Is)NotNull | ... where x.age not null |
Like | findByNameLike | ... where x.name like ?1 |
NotLike | findByNameNotLike | ... where x.name not like ?1 |
StartingWith | findByNameStartingWith | ... where x.name like ?1 (参数会绑定到%后面) |
EndingWith | findByNameEndingWith | ... where x.name like ?1 (参数会绑定在%前面) |
Containing | findByNameContaining | ... where x.name like ?1 (参数会绑定在两个%中间) |
OrderBy | findByAgeOrderByNameDesc | ... where x.age = ?1 order by name desc |
Not | findByNameNot | ... where x.name <> ?1 |
In | findByAgeIn(Collection ages) | ... where x.age in ?1 |
NotIn | findByAgeNotIn(Connection ages) | ... where x.age not in ?1 |
True | findByActiveTrue() | ... where x.active = true |
Flase | findByActiveFalse() | ... where x.active = false |
IgnoreCase | findByNameIgnoreCase | ... where UPPER(x.name) = UPPER(?1) |
最后总结:
以上总结的这些关键字,大家可以直接用来在Dao层构造对应接口。其实从关键字的语法来看,基本就已经介绍了相关功能了,所以用起来其实也很方便,更多关于spring JPA find拓展方法的资料请关注其它相关文章!
相关文章