JPA学习心得四(定义查询方法)

本文详细介绍了Spring Data JPA中的查询方法,包括如何从方法名派生查询、属性表达式、特殊参数处理、限制查询结果、流式查询结果及异步查询。通过实例展示了各种查询方法的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

定义查询方法

存储库代理有两种方法可以从方法名称派生特定于商店的查询。

派生查询两种方式:

  1. 可以直接从方法名称派生查询。
  2. 手动定义查询。

1、查询查找策略:

  • CREATE
  • USE_DECLARED_QUERY
  • CREATE_IF_NOT_FOUND(默认):整合了 CREATE和USE_DECLARED_QUERY

(暂时没理解)

2、查询创建

该机制条前缀find…Byread…Byquery…Bycount…By,和get…By从所述方法和开始分析它的其余部分。

从方法名称创建查询:

public interface PersonRepository extends Repository<User, Long> {

  List<Person> findByEmailAddressAndLastname(EmailAddress emailAddress, String lastname);

  // Enables the distinct flag for the query
  List<Person> findDistinctPeopleByLastnameOrFirstname(String lastname, String firstname);
  List<Person> findPeopleDistinctByLastnameOrFirstname(String lastname, String firstname);

  // Enabling ignoring case for an individual property
  List<Person> findByLastnameIgnoreCase(String lastname);
  // Enabling ignoring case for all suitable properties
  List<Person> findByLastnameAndFirstnameAllIgnoreCase(String lastname, String firstname);

  // Enabling static ORDER BY for a query
  List<Person> findByLastnameOrderByFirstnameAsc(String lastname);
  List<Person> findByLastnameOrderByFirstnameDesc(String lastname);
}

3、属性表达式

假设拥有两个类Person、ZipCode,Person类中拥有一个ZipCode类的属性。可用以下表达式查询ZipCode对应的Person

List<Person> findByAddressZipCode(ZipCode zipCode);

 首先,算法解析会将整个AdderssZipCode作为一个整体属性来查找,如果成功,则使用该属性。如果没有查询到对应该名称的属性,算法将By右边的驼峰部分分为头部和尾部,并尝试找到相应的属性,在我们的示例中,AddressZipCode。如果算法找到具有该头部的属性,则它采用尾部并继续从那里构建树,以刚刚描述的方式将尾部分开。如果第一个分割不匹配,算法会将分割点移动到左侧(AddressZipCode)并继续。

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

要解决这种歧义,您可以_在方法名称中使用手动定义遍历点。所以我们的方法名称最终会像这样:

List<Person> findByAddress_ZipCode(ZipCode zipCode);

4、特殊参数处理

基础结构将识别某些特定类型PageableSort并动态地对您的查询应用分页排序

在查询方法中使用Pageable,Slice和Sort

 

Page<User> findByLastname(String lastname, Pageable pageable);

Slice<User> findByLastname(String lastname, Pageable pageable);

List<User> findByLastname(String lastname, Sort sort);

List<User> findByLastname(String lastname, Pageable pageable);

5、限制查询结果 

 查询方法的结果可以通过关键字来限制,first或者top可以互换使用。

User findFirstByOrderByLastnameAsc();

User findTopByOrderByAgeDesc();

Page<User> queryFirst10ByLastname(String lastname, Pageable pageable);

Slice<User> findTop3ByLastname(String lastname, Pageable pageable);

List<User> findFirst10ByLastname(String lastname, Sort sort);

List<User> findTop10ByLastname(String lastname, Pageable pageable);

 6、流式查询结果

使用Java 8流式传输查询结果 Stream<T>

@Query("select u from User u")
Stream<User> findAllByCustomQueryAndStream();

Stream<User> readAllByFirstnameNotNull();

@Query("select u from User u")
Stream<User> streamAllPaged(Pageable pageable);

 注意:

  • Stream在使用完毕之后需要关闭资源,使用close()方法或者JDK1.7之后的try-with-resources语法。
  • 不是所有的Spring Data模板都支持Stream<T>作为返回类型。

=======================(题外话)try-with-resources使用=======================

try-with-resources是JDK实现的语法糖,JVM虚拟机内部其实还是try-catch-finally语法。

public static void main(String[] args) {
    try (FileInputStream inputStream = new FileInputStream(new File("test"))) {
        System.out.println(inputStream.read());
    } catch (IOException e) {
        throw new RuntimeException(e.getMessage(), e);
    }
}

 使用注意:

  1. 一个外部资源的句柄对象需要实现AutoCloseable接口;
  2. try-with-resource时,如果对外部资源的处理和对外部资源的关闭均遭遇了异常,“关闭异常”将被抑制,“处理异常”将被抛出,但“关闭异常”并没有丢失,而是存放在“处理异常”的被抑制的异常列表中。

7、异步查询结果

通过Spring的异步方法执行异步查询,@Async将一个task提交到Spring TaskExecutor

@Async
Future<User> findByFirstname(String firstname);               

@Async
CompletableFuture<User> findOneByFirstname(String firstname); 

@Async
ListenableFuture<User> findOneByLastname(String lastname);    
  •  使用 java.util.concurrent.Future作为返回类型
  • 使用Java 8  java.util.concurrent.CompletableFuture作为返回类型
  • 使用 org.springframework.util.concurrent.ListenableFuture作为返回类型

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值