Spring反应式:链接存储库结果

时间:2020-03-09 16:00:43

标签: spring project-reactor reactive

Repository repo
Repository otherRepo

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

我该如何使用弹簧反应器?

我可以使用blockFirst()来搜索otherRepo,但这会中断反应链

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

有什么主意吗? 谢谢

2 个答案:

答案 0 :(得分:1)

如果具有这样的存储库,则对于repo1的每个记录,如果需要从repo2查找记录,则可以使用spring数据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

答案 1 :(得分:1)

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个)。您可以减少parallelism中的flatMap(通过提供第二个参数int),也可以使用concatMap依次执行findById查询。