jpa 去重_Spring Data JPA 定义查询方法:创建方法详解和属性表达式

1、Spring Data JPA 中创建数据库查询方法的具体操作说明。方法中的SQL关键词和方法中的数据设置。

2、Spring Data JPA 中对属性字段的解析方式是什么样子的?属性表达式怎么介绍?

三、查询方法的创建

内部基础架构中有个根据方法名的查询生成器机制,对于在存储库的实体上构建约束查询很有用。

该机制方法的前缀有find…By、read…By、query…By、count…By和get…By,从这些方法可以分析它的其余部分(实体里面的字段)。

引入子句可以包含其他表达式,例如在Distinct要创建的查询上设置不同的标志。

然而,第一个By作为分隔符来指示实际标准的开始。在一个非常基本的水平上,你可以定义实体性条件,并与它们串联(And和Or)。

用一句话概括,待查询功能的方法名由查询策略(关键字)、查询字段和一些限制性条件组成。在如下例子中,可以直接在controller里面进行调用以查看效果:

interface PersonRepository extends Repository {

// and的查询关系

List findByEmailAddressAndLastname(EmailAddress emailAddress, String lastname);

//包含distinct去重、or的SQL语法

List findDistinctPeopleByLastnameOrFirstname(Stringlastname, String firstname);

List findPeopleDistinctByLastnameOrFirstname(String lastname, String firstname);

//根据lastname字段查询忽略大小写

List findByLastnamelgnoreCase(String lastname);

//根据lastname和firstname查询equal并且忽略大小写

List findByLastnameAndFirstnameAllIgnoreCase(Stringlastname, String firstname);

//对查询结果根据lastname排序

List findByLastnameOrderByFirstnameAsc(String lastname);

List findByLastnameOrderByFirstnameDesc(String lastname);

}

解析方法的实际结果取决于创建查询的持久性存储。但是,有一些常见的事项需要注意:

表达式通常是可以连接的运算符的属性遍历。你可以使用组合属性表达式AND和OR。你还可以将运算关键字Between、LessThan、GreaterThan、Like作为属性表达式。受支持的操作员可能因数据存储而异,因此请参阅官方参考文档的相应部分内容。

该方法解析器支持设置一个IgnoreCase标志个别特性(例如,findByLastnameIgnoreCase(…))或支持忽略大小写(通常是一个类型的所有属性为String的情况下,例如,findByLastnameAndFirstnameAllIgnoreCase(…))。是否支持忽略示例可能会因存储而异,因此请参阅参考文档中的相关章节,了解特定于场景的查询方法。

可以通过OrderBy在引用属性和提供排序方向(Asc或Desc)的查询方法中附加一个子句来应用静态排序。要创建支持动态排序的查询方法来影响查询结果。

四、关键字列表

Keyword

Sample

JPQL snippet

And

findByLastnameAndFirstname

… where x.lastname = ?1 and x.firstname = ?2

Or

findByLastnameOrFirstname

… where x.lastname = ?1 or x.firstname = ?2

Is,Equals

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 ages)

… where x.age in ?1

NotIn

findByAgeNotIn(Collection age)

… 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)

注意,除了find的前缀之外,我们查看PartTree的源码,还有如

下几种前缀:

private static final String QUERY_PATTERN = ” find | read | get | query | stream’;

private static final String COUNT_PATTERN = "count";

private static final String EXISTS_PATTERN = "exists";

private static final String DELETE_PATTERN = "delete | remove';

使用的时候要配合不同的返回结果进行使用,例如:

interface UserRepository extends CrudRepository {

long countByLastname (String lastname) ;//查询,总数

long deleteByLastname (String lastname) ; / / 根据一个字段进行删除操作

List removeByLastname(String lastname);

}

五、方法的查询策略的属性表达式

属性表达式(Property Expressions)只能引用托管(泛化)实体的直接属性,如前一个示例所示。

在查询创建时,你已经确保解析的属性是托管实体的属性。同时,还可以通过遍历嵌套属性定义约束。

假设一个Person实体对象里面有一个Address属性里面包含一个ZipCode属性。在这种情况下,方法名为:

List findByAddressZipCode(String zipCode);

创建及其查找的过程是:

解析算法首先将整个part(AddressZipCode)解释为属性,并使用该名称(uncapitalized)检查域类的属性。

如果算法成功,就使用该属性。

如果不是,就拆分右侧驼峰部分的信号源到头部和尾部,并试图找出相应的属性,在我们的例子中是AddressZip和Code。

如果算法找到一个具有头部的属性,那么它需要尾部,并从那里继续构建树,然后按照刚刚描述的方式将尾部分割。

如果第一个分割不匹配,就将分割点移动到左边(Address、ZipCode),然后继续。

虽然这在大多数情况下应该起作用,但是算法可能会选择错误的属性。假设Person类也有一个addressZip属性,该算法将在第一个分割轮中匹配,并且基本上会选择错误的属性,最后失败(因为该类型addressZip可能没有code属性)。

要解决这个歧义,可以在方法名称中手动定义遍历点,所以我们的方法名称最终会是:

List findByAddress_ZipCode(String zipCode);

当然Spring JPA里面是将下划线视为保留字符,但是强烈建议遵循标准Java命名约定(不使用属性名称中的下划线,而是使用骆驼示例)。命名属性的时候注意一下这个特性。

可以到PartTreeJpaQuery.class 查询相关的method的name 拆分和实现逻辑。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值