公司的新项目采取spring webflux 的架构,之前没有学习过,刚开始学习的时候,跑通demo 的时候,觉得貌似挺简单的,spring 封装得跟mvc一样,使用者完全无缝感知,框架内部自己完成了异步调用的逻辑,单独使用flux 和mono的时候,还相对简单。
现在有个场景是,我需要从表a里取数据,然后根据a中的关联id 分别从b和c 表取数据,最后封装数据;
一开始的写法,发现返回的结果中,title 和num 并没有值,日志中,异步调用的结果是在结果返回之后复制的
return articleRepository.findAll().map(article -> {
ArticleVO articleVO = new ArticleVO();
articleVO.setId(article.getId());
articleVO.setName(article.getName());
return articleVO;
}).map(articleVO -> {
articleTitleRepository.findByArticleId(articleVO.getId()).subscribe(articleTitle -> articleVO.setTitle(articleTitle.getTitle()));
return articleVO;
}).map(articleVO -> {
articleExtRepository.findByArticleId(articleVO.getId()).subscribe(articleExt -> articleVO.setNum(articleExt.getNum()));
return articleVO;
});
后来各种尝试会返回的方法,目前在学习阶段,对webflux 还不是太熟悉,所以相关的原理还没有明白,先记录下来,等理解了再看
return articleRepository.findAll().map(article -> {
ArticleVO articleVO = new ArticleVO();
articleVO.setId(article.getId());
articleVO.setName(article.getName());
return articleVO;
}).flatMap(articleVO -> {
return articleTitleRepository.findByArticleId(articleVO.getId()).switchIfEmpty(Mono.just(new ArticleTitle())).map(articleTitle -> {
articleVO.setTitle(articleTitle.getTitle());
return articleVO;
});
}).flatMap(articleVO -> {
return articleExtRepository.findByArticleId(articleVO.getId()).switchIfEmpty(Mono.just(new ArticleExt())).map(articleExt -> {
articleVO.setNum(articleExt.getNum());
return articleVO;
});
});
另一种写法:
return articleRepository.findAll().map(article -> {
ArticleVO articleVO = new ArticleVO();
articleVO.setId(article.getId());
articleVO.setName(article.getName());
return articleVO;
}).flatMap(articleVO -> {
Mono<ArticleTitle> articleTitleMono = articleTitleRepository.findByArticleId(articleVO.getId()).defaultIfEmpty(new ArticleTitle());
Mono<ArticleExt> articleExtMono = articleExtRepository.findByArticleId(articleVO.getId()).defaultIfEmpty(new ArticleExt());
return Mono.zip(articleTitleMono, articleExtMono).map(objects -> {
articleVO.setNum(objects.getT2().getNum());
articleVO.setTitle(objects.getT1().getTitle());
return articleVO;
});
});