【问题标题】:Spring reactive: Chaining repository resultsSpring reactive:链接存储库结果
【发布时间】:2020-03-09 16:00:43
【问题描述】:
Repository repo
Repository otherRepo

foreach entity : repo.FindAll() {
    entityFind = otherRepo.FindById(entity.Prop)
    if (entityFind != null) {
        return entityFind 
    }
}

如何使用 spring 反应式做到这一点?

我可以使用 blockFirst() 在 otherRepo 中搜索,但它会破坏反应链

我也尝试过使用 handle() 来控制流程,但是当我找到一个项目时我不会中断流程

有什么想法吗? 谢谢

【问题讨论】:

    标签: spring project-reactor reactive


    【解决方案1】:

    如果您有这样的 repos,对于 repo1 的每条记录,如果您需要从 repo2 中查找记录,您可能可以使用 spring data JPQL 加入表并改用您的自定义方法,因为您当前的方法可能会对性能产生影响.

    由于您似乎只对第一条记录感兴趣,只是给您一个想法,我们可以实现这样的目标。

    return Flux.fromIterable(repo.findAll()) //assuming it returns a list
               .map(entity -> otherRepo.findById(entity.property)) // for each entity we query the other repo
               .filter(Objects::nonNull) // replace it with Optional::isPresent if it is optional
               .next();   //converts the flux to mono with the first record
    

    【讨论】:

    • 我使用 Cassandra。此解决方案的问题在于,如果您在 repo1 中有 n 个元素,并且在第一个元素中的 repo2 中找到了该元素,则将在 repo2 中执行不必要的搜索。谢谢你的回答
    【解决方案2】:

    vins 的答案是假设存储库是非反应式的,所以这里是完全反应式的:

    return repo.findAll() //assuming reactive repository, which returns Flux<Entity>
        .flatMap(entity -> otherRepo.findById(entity.property)) //findById returns an empty Mono if id not found, which basically gets ignored by flatMap
        .next(); //first record is turned into a Mono, and the Flux is cancelled
    

    请注意,正如您所说,这可能会导致向 Cassandra 发出不必要的请求(然后被 next() 取消)。这是因为flatMap 允许多个并发请求(默认为 256 个)。您可以减少flatMapparallelism(通过提供第二个参数int)或使用concatMap 连续执行findById 查询。

    【讨论】:

      猜你喜欢
      • 2022-06-25
      • 1970-01-01
      • 1970-01-01
      • 2017-12-13
      • 1970-01-01
      • 2018-06-27
      • 2020-07-26
      • 2018-07-25
      • 1970-01-01
      相关资源
      最近更新 更多