1. 概述

Spring Data Repositories 提供了灵活的方式,在ListStream中查询大量数据。在这篇教程中,我们将学习如何在ListStream中查询数据,并了解何时使用它们。

2. ListStream

我们知道,社交媒体网站拥有数百万用户的详细信息。假设我们需要找到所有年龄大于20岁的用户。本节将通过返回ListStream的查询来解决这个问题,并理解这两种查询方式的工作原理。

由于我们将使用代码示例,运行这些示例需要一些前提条件。我们使用的是H2数据库。User是我们的实体,具有firstNamelastNameage等属性。我们在测试类的setup方法中持久化了一些用户。我们使用了Java Faker库为这个实体生成随机数据。

2.1. List

在Java中,List是一个接口,有多种实现,如ArrayListLinkedList等,用于存储一组数据。

以下示例中,我们将编写一个Spring Data JPA测试,以List形式加载所有用户,并断言结果中的所有用户都大于20岁。

Spring Data提供了多种查询方式,这里我们将使用query方法构建查询。

我们将使用此query方法加载List中的用户:

List<User> findByAgeGreaterThan20();

现在,让我们编写一个测试用例看看它是如何工作的:

@Test
public void whenAgeIs20_thenItShouldReturnAllUsersWhoseAgeIsGreaterThan20InAList() {
  List<User> users = userRepository.findByAgeGreaterThan(20);
  assertThat(users).isNotEmpty();
  assertThat(users.stream().map(User::getAge).allMatch(age -> age > 20)).isTrue();
}

这个测试用例查询用户并断言所有用户都大于20岁。在这种情况下,客户端会一次性获取所有用户,而在查询完成后,底层数据库资源会被关闭,除非我们手动保持它们打开状态。

2.2. Stream

Stream是数据流动的管道,它支持的一些中间方法会在数据流动过程中对数据执行操作。

虽然在List中查询数据是获取集合的常见方式,但在作为数据库结果使用时,有一些关于其使用的注意事项,我们将在下一节中讨论。现在,让我们了解如何在Stream中查询数据。

这次我们将使用这个query方法加载Stream中的用户:

Stream<User> findByAgeGreaterThan20();

现在,让我们编写一个测试用例:

@Test
public void whenAgeIs20_thenItShouldReturnAllUsersWhoseAgeIsGreaterThan20InAStream() {
  Stream<User> users = userRepository.findAllByAgeGreaterThan(20);
  assertThat(users).isNotNull();
  assertThat(users.map(User::getAge).allMatch(age -> age > 20)).isTrue();
}

我们可以清楚地看到,通过获取Stream中的结果,可以直接对其进行操作。一旦得到第一个用户,客户端可以立即处理,而底层数据库资源在处理流中的所有用户时保持打开状态

为了确保EntityManager直到处理完Stream中的所有结果才关闭,必须在Stream查询上使用@Transactional注解。此外,Stream查询包装在try-with-resources语句中也是好的实践

现在,既然我们了解了如何使用它们,接下来我们将探讨何时最适合使用每一种。

3. 何时使用

在适当的情境下使用StreamList非常重要,因为在不适用的情况下使用它们可能会导致性能下降或意外行为。始终评估替代方案并选择最适合问题的一个。

List适用于需要一次性获取所有结果的小型结果集,而Stream更适合可以逐个处理的大结果集,并且当客户端需要Stream而不是Collection时。

Stream中查询数据时,如果数据库查询和中间Stream方法都能产生相同的结果,我们应该优先选择数据库查询。

4. 总结

在这篇文章中,我们学习了在使用Spring Data Repositories时如何使用ListStream

我们也了解到,当客户端需要一次性获取所有结果时应使用List,而在Stream中,客户端可以在收到第一个结果后立即开始工作。我们还讨论了对底层数据库资源的影响以及何时最好使用它们。

本文中所有使用的代码示例可在GitHub上找到。