原标题:Spring认证|Spring Data JPA 参考文档二(内容来源:Spring中国教育管理中心)
4.4.6.返回集合或可迭代对象的存储库方法
查询方法,返回多个结果可以使用标准的Java Iterable,List和Set。除此之外,我们支持返回 Spring Data 的Streamable、 的自定义扩展Iterable以及Vavr提供的集合类型。请参阅解释所有可能的查询方法返回类型的附录。
使用 Streamable 作为查询方法返回类型
您可以使用任何集合类型的Streamable替代Iterable品。它提供了访问非并行Stream(缺少 from Iterable)的便捷方法,以及直接….filter(…)和….map(…)覆盖元素并将其连接Streamable到其他元素的能力:
示例 19. 使用 Streamable 组合查询方法结果
interface PersonRepository extends Repository<Person, Long> {
Streamable<Person> findByFirstnameContaining(String firstname);
Streamable<Person> findByLastnameContaining(String lastname);
}
Streamable<Person> result = repository.findByFirstnameContaining("av")
.and(repository.findByLastnameContaining("ea"));
返回自定义流包装器类型
为集合提供专用包装器类型是一种常用模式,用于为返回多个元素的查询结果提供 API。通常,通过调用存储库方法返回类集合类型并手动创建包装器类型的实例来使用这些类型。您可以避免额外的步骤,因为 Spring Data 允许您使用这些包装器类型作为查询方法返回类型,如果它们满足以下条件:
- 类型实现Streamable.
- 的类型公开任一个构造或命名静态工厂法of(…)或valueOf(…)该取Streamable作为参数。
以下清单显示了一个示例:
class Product {
MonetaryAmount getPrice() { … }
}
@RequiredArgsConstructor(staticName = "of")
class Products implements Streamable<Product> {
private final Streamable<Product> streamable;
public MonetaryAmount getTotal() {
return streamable.stream()
.map(Priced::getPrice)
.reduce(Money.of(0), MonetaryAmount::add);
}
@Override
public Iterator<Product> iterator() {
return streamable.iterator();
}
}
interface ProductRepository implements Repository<Product, Long> {
Products findAllByDescriptionContaining(String text);
}
一个Product暴露的API来访问产品的价格实体。
Streamable<Product>可以通过使用Products.of(…)(使用Lombok注释创建的工厂方法)构造的的包装器类型。采用Streamable<Product>will的标准构造函数也可以。
包装器类型公开了一个额外的API,在Streamable<Product>.
实现Streamable接口并委托给实际结果。
该包装器类型Products可以直接用作查询方法返回类型。您不需要Streamable<Product>在存储库客户端中的查询之后返回并手动包装它。
支持 Vavr 集合
Vavr是一个包含 Java 函数式编程概念的库。它附带一组自定义集合类型,您可以将其用作查询方法返回类型,如下表所示:
您可以使用第一列(或其子类型)中的类型作为查询方法返回类型,并根据实际查询结果(第三列)的 Java 类型获取第二列中的类型作为实现类型。或者,您可以声明Traversable(Iterable相当于Vavr ),然后我们从实际返回值派生实现类