13.1.2 定义响应式 Repository

在第 3 章和第 4 章中,我们将 Repository 定义为扩展 Spring Data 的 CrudRepository 接口。但那个基本 Repository 接口处理的是单个对象和可遍历集合。相反,我们希望响应式 Repository 能够处理 Mono 和 Flux 对象。

这就是为什么 Spring 提供了 ReactiveCrudepository 来定义响应式 Repository。ReactiveCrudepository 的操作与 CrudRepository 非常相似。要创建响应式 Repository,需扩展 ReactiveCrudepository 接口,例如:

package tacos.data;

import org.springframework.data.repository.reactive.ReactiveCrudRepository;

import tacos.TacoOrder;

public interface OrderRepository
      extends ReactiveCrudRepository<TacoOrder, Long> {
}

从表面上看,这个 OrderRepository 与我们在第 3 章和第 4 章中定义的 OrderRepository 之间的唯一区别是,它扩展了 ReactiveCrudRepository,而不是 CrudRepository。但是最显著不同其实是,这个方法返回 Mono 和 Flux 类型,而不是单个 TacoOrder 或 Iterable<TacoOrder>。举两个例子:findById() 方法返回 Mono<TacoOrder>findAll()返回 Flux<TacoOrder>

要了解此响应式 Repository 在实际如何工作,假设您希望获取所有 TacoOrder 对象,并将其名称打印到标准输出。这种情况下,您可以 编写一些代码,如清单 13.4 所示。

清单 13.4 调用响应式 Repository 方法。

@Autowired
OrderRepository orderRepo;

...

orderRepository.findAll()
  .doOnNext(order -> {
    System.out.println(
      "Deliver to: " + order.getDeliveryName());
    })
  .subscribe();

在这里,对 findAll() 的调用返回一个 Flux<TacoOrder>。我们在其上添加了一个 doOnNext() 方法以打印收货人名称。最后,调用 subscribe() 启动了数据传输。

在第 3 章的 Spring Data JDBC 示例中,TacoOrder 是 Taco 的聚合根。因此,Taco 对象作为 TacoOrder 的一部分被持久化了,而没有必要定义一个专门用于 Taco 持久性的 Repository。但是 Spring Data R2DBC 不能以这种方式支持聚合,因此我们需要一个 TacoRepository,通过它持久化 Taco 对象。这个 Repository 请参见清单 13.5。

清单 13.5 使用响应式 Repository 持久化 Taco 对象。

package tacos.data;

import org.springframework.data.repository.reactive.ReactiveCrudRepository;
import tacos.Taco;

public interface TacoRepository
      extends ReactiveCrudRepository<Taco, Long> {
}

如您所见,TacoRepository 与 OrderRepository 没有太大区别。它扩展 ReactiveCrudepository,在使用 Taco 持久化时为我们提供响应式类型。这里没有太多可说的。

另一方面,IngredientRepository 稍微有趣一些,如清单 13.6 所示。

清单 13.6 使用响应式 Repository 持久化 Ingredient 对象。

package tacos.data;

import org.springframework.data.repository.reactive.ReactiveCrudRepository;

import reactor.core.publisher.Mono;
import tacos.Ingredient;

public interface IngredientRepository
      extends ReactiveCrudRepository<Ingredient, Long> {

  Mono<Ingredient> findBySlug(String slug);

}

与我们的其他两个响应式 Repository 一样,IngredientRepository 扩展了 ReactiveCrudRepository。但是因为我们可能需要一种基于 slug 值来查找 Ingredient 对象的方法,IngredientRepository 包含一个 findBySlug()方法,该方法返回一个 Mono<Ingredient>

现在让我们看看如何编写测试类,来验证我们的 Repository 是否工作。

results matching ""

    No results matching ""