Spring Webflux - 反应式存储库 saveAll(Iterable<S>) 与 saveAll(Publisher<S>)

Spring Webflux - reactive repository saveAll(Iterable<S>) vs saveAll(Publisher<S>)

关于 webflux 反应式存储库的小问题,尤其是关于方法 saveAll Flux saveAll(Iterable var1);与 Flux saveAll(Publisher var1);

想对比一下,我写了以下内容:

@Controller
@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class);
    }

    @Autowired
    private SomeReactiveRepository someReactiveRepository;

    @PostMapping(path = "/saveListInsideMono", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public Mono<QuestionResponse> saveListInsideMono(@RequestBody Mono<QuestionRequest> questionRequestMono) {
        //just doing some business transformation on the list inside the mono
        Mono<List<String>> enhancedStringListMono = questionRequestMono.map(questionRequest -> enhance(questionRequest));
        //take the pojo inside the mono and map it to a saveAllAndConvertToResponse method (see next method)
        Mono<QuestionResponse> questionResponseMono = enhancedStringListMono.map(enhancedStringList -> saveAllAndConvertToResponse(enhancedStringList));
        return questionResponseMono;
    }

    private QuestionResponse saveAllAndConvertToResponse(List<String> enhancedStringList) {
        // use the repository <S extends T> Flux<S> saveAll(Iterable<S> var1); + subscribe
        return someReactiveRepository.saveAll(enhancedStringList).thenReturn(new QuestionResponse(enhancedStringList));
    //this also works but not good to subscribe
        //someReactiveRepository.saveAll(enhancedStringList).subscribe();
        //return new QuestionResponse(enhancedStringList);
    }

    @PostMapping(path = "/saveFlux", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public Mono<QuestionResponse> saveFlux(@RequestBody Mono<QuestionRequest> questionRequestMono) {
        //just doing some business transformation on the list inside the mono
        Mono<List<String>> enhancedStringListMono = questionRequestMono.map(questionRequest -> enhance(questionRequest));
        // use the repository <S extends T> Flux<S> saveAll(Publisher<S> var1); to save the flatMapMany + fromIterable directly
        Flux<String> enhancedStringFlux = someReactiveRepository.saveAll(enhancedStringListMono.flatMapMany(Flux::fromIterable));
        Mono<QuestionResponse> questionResponseMono = enhancedStringFlux.collectList().map(enhancedString -> convertToResponse(enhancedString));
        return questionResponseMono;
    }

    private QuestionResponse convertToResponse(List<String> enhancedStringList) {
        //return the object needed
        return new QuestionResponse(enhancedStringList);
    }

    private static List<String> enhance(QuestionRequest questionRequest) {
        //dummy business transformation logic
        List<String> baseList = questionRequest.getList();
        List<String> enhancedList = baseList.stream().map(oneString -> "enhanced" + oneString).collect(Collectors.toList());
        return enhancedList;
    }

    public class QuestionRequest {
        private List<String> list;

        public List<String> getList() {
            return list;
        }
    }

    public class QuestionResponse {
        private List<String> enhancedList;

        public QuestionResponse(List<String> enhancedList) {
            this.enhancedList = enhancedList;
        }
    }

}

就“正确性”而言,这两个代码都符合预期。一切都成功持久化。

但就性能、反应范式、数据库的 IO 利用率、Netty Core 使用而言,“最佳”解决方案是什么?为什么?

谢谢

这完全取决于您当前拥有的对象。如果您有 Flux 个对象,请使用采用 Publisher 的 saveAll 方法。如果您有实际的 Collection 个对象,请使用采用 Iterable.

的 saveAll 方法

例如,如果您查看实现 SimpleReactiveCassandraRepository,saveAll 的实现采用 Iterable 只是将其包装在 Flux 中并委托给接受 [=11] 的 saveAll 方法=]

public <S extends T> Flux<S> saveAll(Iterable<S> entities) {

    Assert.notNull(entities, "The given Iterable of entities must not be null");

    return saveAll(Flux.fromIterable(entities));
}

因此,在 IO 利用率或 netty 核心使用方面应该没有差异。此外,两者都遵循反应式范式。

SimpleReactiveCassandraRepository Code