我对 Java 中响应式的使用还很陌生。以下是我面临的问题。
我开发了一个带有控制器、服务和存储层以及 R2DBC 驱动程序的 springboot-REST 应用程序。
public interface ItemRepository extends R2dbcRepository<Item, String>
此存储库是从服务层调用的。
服务层有以下代码库
(从逻辑上讲,在这种情况下我不需要 monoItemFromDB,但只需忽略该逻辑问题,因为我对技术方面更感兴趣)
public Mono<Item> modifyItem(Mono<Item> itemMono, int id ) {
Mono<Item> monoItemFromDB = itemRepo.findById(id);
return itemMono
.flatMap(item -> {
monoItemFromDB.subscribe(dbItem -> item.setId(dbItem.getId()));
return itemRepo.save(item);
});
}
上述方法效果很好,数据保存在嵌入式数据库中。 但下面的代码与上面的代码有点不同,它没有将数据保存在数据库中。
public Mono<Item> modifyItem(Mono<Item> itemMono, int id ) {
Mono<Item> monoItemFromDB = itemRepo.findById(id);
monoItemFromDB.subscribe(dbItem -> {
itemMono.flatMap(item -> {
item.setId(dbItem.getId());
return itemRepo.save(item);
});
});
return monoItemFromDB;
}
在第一个场景中,我将 itemMono 展平,然后执行在 monoItemFromDB 上订阅以获取 id 并将项目保存到存储库的两步过程。
在第二种情况下,我订阅 monoItemFromDB,然后执行压平 itemMono 以设置 id 并将项目保存到存储库的两步过程
请求有人解释我在第二种编写方法时犯的错误。
提前致谢!
斯里拉姆
您不使用
subscribe
来做任何额外的工作。 Subscribe 由所有中间步骤(例如 .flatMap()
)调用,并且除了启动所有内容的最后一步之外,它不应该存在于您的代码中。如果您有 WebFlux 应用程序,那么您不应该拥有它,因为订阅是 WebFlux 的工作。
您还返回第一个
monoItemFromDB
,忽略接下来的步骤。
可能应该是:
public Mono<Item> modifyItem(Mono<Item> itemMono, int id ) {
Mono<Item> monoItemFromDB = itemRepo.findById(id);
Mono<Item> monoItemSaved = monoItemFromDB.flatMap(dbItem -> {
return itemMono.flatMap(item -> {
item.setId(dbItem.getId());
return itemRepo.save(item);
});
});
return monoItemSaved;
}
或者您可以同时开始(订阅):
public Mono<Item> modifyItem(Mono<Item> itemMono, int id ) {
return itemRepo.findById(id).zip(itemMono).flatMap(both -> {
Item item = both.getT2();
Item dbItem = both.getT1();
item.setId(dbItem.getId());
return itemRepo.save(item);
});
});
}