【问题标题】:Obtaining a nested objects using Spring Data R2DBC使用 Spring Data R2DBC 获取嵌套对象
【发布时间】:2020-01-21 12:57:50
【问题描述】:

我是 Project Reactor 和 R2DBC 的新手。如何使用 Spring Data R2DBC 响应式存储库正确接收和合并 Flux<Child>Mono<Parent>

家长:

@Table("parent")
public class Parent{

@Id
private Long id;
private String name;

@Transient
private Flux<Child> children;

父存储库:

interface ParentRepository extends ReactiveCrudRepository<Parent, Long> {

@Query()
Mono<Parent> findOneByName(String name);

孩子:

@Table("child")
public class Child{

@Id
private Long id;

子存储库:

interface ChildRepository extends ReactiveCrudRepository<Child, Long> {

@Query()
Flux<Child> findAllByParentId(Long parentId);

ParentPersistenceAdapter:

public Mono<Parent> findParent(String parentName) {
    return parentRepository.findOneByName(parentName)
      //how to invoke childRepository.findAllByParentId()
      //and set this Flux to Parent's Mono

}

我的解决办法是:

public Mono<Parent> findParent(String parentName) {
    return parentRepository.findOneByName(parentName)
      .map(parent -> {
            Flux<Child> children = childRepository.findAllByParentId(parent.getId())
            children.subscribe();
            return parent.setChildren(children );
        });      
}

【问题讨论】:

    标签: java reactive-programming project-reactor spring-data-r2dbc r2dbc


    【解决方案1】:

    假设存在withChildren(Flux&lt;Child&gt; children) type method,你可以这样做:

    parentRepository.findById(parentId)
        .map(p -> p.withChildren(childRepository.findAllByParentId(parentId)));
    

    但是,这有点奇怪 - 您通常不会在像这样的 DAO 上拥有 Flux,因为您需要订阅它并单独管理内容。您通常会使用List&lt;Child&gt;。对于这种情况,您可以将子流收集为一个列表,将zip() 对应的Mono 发布者组合在一起,然后将它们组合成您的最终Parent 对象。

    所以假设一个withChildren(List&lt;Child&gt; children) 方法:

    Mono.zip(parentRepository.findById(parentId),
        childRepository.findAllByParentId(parentId).collectList(),
        (t1,t2) -> t1.withChildren(t2));
    

    【讨论】:

    • 感谢您的回答。如果只是复制Flux&lt;Child&gt;,那么childRepository.findAllByParentId(parentId)不会被执行,因为我需要订阅这个Flux&lt;Role&gt;。如何使用 Project Reactor 操作符来做到这一点?
    • 但是我想让应用程序完全响应,那么我需要使用 Flux 而不是使用集合,对吧?
    • @KirillValyushko 不,这没有任何意义。 Flux 是一个数据流,它不能替代使用集合。完全反应就是非阻塞(collectList() 是非阻塞的,因为它提供了一个Mono&lt;List&gt;)。您可能希望阅读有关反应器和反应式编程的一般知识,否则您可能会越来越陷入困境。
    • @MichaelBerry 如果parentRepository 返回Flux&lt;Parent&gt;,我们如何实现这一点?对数据库中找到的每个 Parent 对象执行 NchildRepository.findAllByParentId(parentId)
    • @MichaelBerry 如果我想检索所有带有孩子的parent 元素而不为每个父母调用findAllByParentId,它应该是什么样子?可能吗?编辑:对不起,我没有注意到@HalayemAnis 也问过同样的问题.. 但也许值得再次联系你:)
    猜你喜欢
    • 2015-07-31
    • 2018-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-07
    • 1970-01-01
    • 1970-01-01
    • 2020-11-25
    相关资源
    最近更新 更多