英文:
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 = "/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;
}
}
}
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 <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));
}
As a result, there should no difference in terms of IO utilisation or netty core usage. Also, both follow the reactive paradigm.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论