如何使用WebFlux简洁实现主对象与关联子对象的获取操作
优化后的响应式实现方案
最简写法(推荐)
直接在单次flatMap内完成属性填充,无需拆分Tuple,代码逻辑线性清晰:
Mono<Page> pageMono = repo.getPageById(47) .flatMap(page -> repo.getBlocksByPageId(47) .collectList() .doOnNext(page::setBlocks) .thenReturn(page) );
逻辑说明:
- 先查询指定id的Page对象
- 拿到Page后触发关联Block的查询,将结果收集为List
- 用
doOnNext操作符给当前Page设置blocks属性 - 最后直接返回填充完成的Page对象,全程无额外的中间转换
不可变对象适配写法
如果你的Page实体是不可变的(比如Java 16+的Record类),不允许修改属性,可以用简化的zipWith写法,省略多余的Mono.just包装和二次flatMap:
Mono<Page> pageMono = repo.getPageById(47) .zipWith(repo.getBlocksByPageId(47).collectList()) .map(tuple -> new Page(tuple.getT1().getId(), tuple.getT1().getTitle(), tuple.getT2()));
如果是可变对象的场景,这个写法也可以简化为:
Mono<Page> pageMono = repo.getPageById(47) .zipWith(repo.getBlocksByPageId(47).collectList()) .map(tuple -> { Page page = tuple.getT1(); page.setBlocks(tuple.getT2()); return page; });
持久层层面优化(更彻底)
如果你使用的是Spring Data R2DBC、Hibernate Reactive这类支持关联查询的响应式持久层框架,可以直接在仓库层定义关联抓取的查询方法,业务层无需手动组装属性:
// 仓库接口定义 @Query("SELECT p FROM Page p LEFT JOIN FETCH p.blocks WHERE p.id = :pageId") Mono<Page> findPageWithBlocksById(Long pageId); // 业务层直接调用即可拿到填充好blocks的Page对象 Mono<Page> pageMono = repo.findPageWithBlocksById(47);
内容的提问来源于stack exchange,提问作者Fredrik Rambris
相关产品推荐
相关产品推荐

