Spring Webflux – 响应式存储库 saveAll(Iterable<S>) vs saveAll(Publisher<S>)

huangapple go评论71阅读模式
英文:

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

问题

关于WebFlux响应式存储库中saveAll方法的小问题,特别是<S extends T> Flux<S> saveAll(Iterable<S> var1);<S extends T> Flux<S> saveAll(Publisher<S> var1);方法的比较。

在"正确性"方面,这两段代码都按预期运行。所有数据都成功持久化了。

但就性能、响应式范式、与数据库的IO利用率、Netty核心使用等方面来看,哪个是“最佳”解决方案,以及为什么呢?

谢谢你。

翻译完成,不提供问题的回答。

英文:

Small question about the webflux reactive repository, especially about the methods saveAll <S extends T> Flux<S> saveAll(Iterable<S> var1); versus <S extends T> Flux<S> saveAll(Publisher<S> var1);

Wanted to compare, I wrote the following:

@Controller
@SpringBootApplication
public class Application {

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

    @Autowired
    private SomeReactiveRepository someReactiveRepository;

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

    private QuestionResponse saveAllAndConvertToResponse(List&lt;String&gt; enhancedStringList) {
        // use the repository &lt;S extends T&gt; Flux&lt;S&gt; saveAll(Iterable&lt;S&gt; 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 = &quot;/saveFlux&quot;, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public Mono&lt;QuestionResponse&gt; saveFlux(@RequestBody Mono&lt;QuestionRequest&gt; questionRequestMono) {
        //just doing some business transformation on the list inside the mono
        Mono&lt;List&lt;String&gt;&gt; enhancedStringListMono = questionRequestMono.map(questionRequest -&gt; enhance(questionRequest));
        // use the repository &lt;S extends T&gt; Flux&lt;S&gt; saveAll(Publisher&lt;S&gt; var1); to save the flatMapMany + fromIterable directly
        Flux&lt;String&gt; enhancedStringFlux = someReactiveRepository.saveAll(enhancedStringListMono.flatMapMany(Flux::fromIterable));
        Mono&lt;QuestionResponse&gt; questionResponseMono = enhancedStringFlux.collectList().map(enhancedString -&gt; convertToResponse(enhancedString));
        return questionResponseMono;
    }

    private QuestionResponse convertToResponse(List&lt;String&gt; enhancedStringList) {
        //return the object needed
        return new QuestionResponse(enhancedStringList);
    }

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

    public class QuestionRequest {
        private List&lt;String&gt; list;

        public List&lt;String&gt; getList() {
            return list;
        }
    }

    public class QuestionResponse {
        private List&lt;String&gt; enhancedList;

        public QuestionResponse(List&lt;String&gt; enhancedList) {
            this.enhancedList = enhancedList;
        }
    }

}

In terms of "correctness" both codes are doing what is expected. Everything is persisted successfully.

But in terms of performance, reactive paradigm, IO Utilisations to DB, Netty Core usage, what is the "best" solution and why please?

Thank you

答案1

得分: 1

根据您目前拥有的对象而定。如果您有对象的 Flux,请使用接受 Publisher 的 saveAll 方法。如果您有实际的对象 Collection,请使用接受 Iterable 的 saveAll 方法。

以一个示例来说明,如果您查看 SimpleReactiveCassandraRepository 的实现,接受 Iterable 的 saveAll 方法只是将其包装在 Flux 中,并委托给接受 Flux 的 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核心使用方面不应有差异。而且,两者都遵循响应式编程范 paradigm。

SimpleReactiveCassandraRepository 代码

英文:

It all depends on what objects you currently have. If you have a Flux of objects, use the saveAll method that takes a Publisher. If you have the actual Collection of objects, use the saveAll method that takes an Iterable.

As an example, if you look at the implementation SimpleReactiveCassandraRepository the implementation of saveAll that takes an Iterable just wraps it in a Flux and delegates to the saveAll method that accepts a Flux

public &lt;S extends T&gt; Flux&lt;S&gt; saveAll(Iterable&lt;S&gt; entities) {

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

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

As a result, there should no difference in terms of IO utilisation or netty core usage. Also, both follow the reactive paradigm.

SimpleReactiveCassandraRepository Code

huangapple
  • 本文由 发表于 2020年9月1日 21:55:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/63689135.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定