问题描述
我对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",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
,则采用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核心利用率方面应该没有差异。而且,它们都遵循反应式范例。