Spring JPA之find拓展方法示例详解

2023-05-18 05:05:56 示例 拓展 详解

前言

前两篇我们详细了解了 findByIdfindAll 以及 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&lt;User&gt; 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 条件2Dao 层

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片段
AndfindByNameAndAge... where x.name = ?1 and x.age = ?2
OrfindByNameOrAge... where x.name = ?1 or x.age = ?2
Is,EqualsfindByName,findByNameIs,findByNameEquals... where x.name = ?1
BetweenfindByAgeBetween... where x.age between ?1 and ?2
LessThanfindByAgeLessThan... where x.age < ?1
LessThanEqualfindByAgeLessThanEqual... where x.age <= ?1
GreaterThanfindByAgeGreaterThan... where x.age > ?1
GreaterThanEqualfindByAgeGreaterThanEqual... where x.age >= ?1
AfterfindByAgeAfter... where x.age > ?1
BeforefindByAgeBefore... where x.age< ?1
IsNullfindByAgeIsNull... where x.age is null
IsNotNull,NotNullfindByAge(Is)NotNull... where x.age not null
LikefindByNameLike... where x.name like ?1
NotLikefindByNameNotLike... where x.name not like ?1
StartingWithfindByNameStartingWith... where x.name like ?1 (参数会绑定到%后面)
EndingWithfindByNameEndingWith... where x.name like ?1 (参数会绑定在%前面)
ContainingfindByNameContaining... where x.name like ?1 (参数会绑定在两个%中间)
OrderByfindByAgeOrderByNameDesc... where x.age = ?1 order by name desc
NotfindByNameNot... where x.name <> ?1
InfindByAgeIn(Collection ages)... where x.age in ?1
NotInfindByAgeNotIn(Connection ages)... where x.age not in ?1
TruefindByActiveTrue()... where x.active = true
FlasefindByActiveFalse()... where x.active = false
IgnoreCasefindByNameIgnoreCase... where UPPER(x.name) = UPPER(?1)

最后总结:

以上总结的这些关键字,大家可以直接用来在Dao层构造对应接口。其实从关键字的语法来看,基本就已经介绍了相关功能了,所以用起来其实也很方便,更多关于spring JPA find拓展方法的资料请关注其它相关文章!

相关文章