【问题标题】:How to implement OneToMany, ManyToOne and ManyToMany with R2DBC in a project which previously used JPA?如何在以前使用 JPA 的项目中使用 R2DBC 实现 OneToMany、ManyToOne 和 ManyToMany?
【发布时间】:2020-05-16 01:37:59
【问题描述】:

我必须重新实现一些后端服务,其中一项主要要求是使整个流程具有反应性。以前,服务使用 PostgreSQL 的休眠,所以提到的连接是由框架提供的。

由于我必须保留原始数据库并仅更改服务实现,因此我必须使用 r2dbc-postgresql。我找不到关于这个主题的任何资源,但我最好的猜测是做一些类似于我对 JDBC 所做的事情,并在我的实体之间引入一些新的连接表。

  1. 这是一种正确的方法还是我应该考虑一些不同的解决方案?
  2. 实现上述连接的步骤是什么?

【问题讨论】:

    标签: postgresql spring-webflux project-reactor spring-data-r2dbc r2dbc


    【解决方案1】:

    我正在研究类似的东西并得出相同的结论 (1),因为 R2DBC 中不支持关系。 为了迁移一对多关系,我首先将包含“许多”实体的集合添加到“一个”实体中的@Transient。 持久化“一个”实体是使用反应序列中的以下步骤完成的:

    1. 保留“许多”实体。这是为了能够在“一个”实体中更新这些,以便为“多个”实体分配 ID。
    2. 坚持“一个”实体。
    3. 保持关系。我可以在这个阶段执行此操作,因为我现在拥有所有相关实体的 ID。对于关系,我引入了一个辅助实体,类似于 OneManyRelation 和相应的存储库。

    在代码中是这样的:

    public <S extends Drawing> Mono<S> save(final S inDrawing) {
        final List<Shape> theDrawingShapes = inDrawing.getShapes();
    
        return Mono.defer(() -> {
            return Flux.fromIterable(theDrawingShapes)
                .log()
                .flatMap(theDrawingShape -> {
                    /* Save the shapes contained in the drawing. */
                    if (theDrawingShape instanceof Circle) {
                        final Circle theUnsavedCircle = (Circle) theDrawingShape;
                        return mCircleRepository.save(theUnsavedCircle);
                    } else if (theDrawingShape instanceof Rectangle) {
                        final Rectangle theUnsavedRectangle = (Rectangle) theDrawingShape;
                        return mRectangleRepository.save(theUnsavedRectangle);
                    } else {
                        LOGGER.warn("Unrecognized entity type: {}",
                            theDrawingShape.getClass().getName());
                        return Mono.just(theDrawingShape);
                    }
                })
                /* Update the drawing, setting the shapes of the drawing to the saved shapes. */
                .collectList()
                .map(theSavedShapesList -> {
                    inDrawing.setShapes(new ArrayList<>(theSavedShapesList));
                    return inDrawing;
                })
                /* Save the drawing itself. */
                .flatMap(theDrawing -> super.save(theDrawing))
                .flatMap(theDrawing -> {
                    /* Save the relations between the drawing and the shapes of the drawing. */
                    return Flux.fromIterable(theDrawing.getShapes())
                        .flatMap(theDrawingShape -> {
                            final var theDrawingShapeRelation = new DrawingShapesRelation();
                            theDrawingShapeRelation.setDrawingId(theDrawing.getId());
                            theDrawingShapeRelation.setShapeId(theDrawingShape.getId());
                            theDrawingShapeRelation.setShapeType(theDrawingShape.getClass()
                                .getName());
                            return mDrawingShapesRelationRepository.save(theDrawingShapeRelation);
                        })
                        .collectList()
                        .map(theDrawingShapesRelationList -> theDrawing);
                });
        });
    }
    

    到目前为止,我的结论是,除非您确定切换到 R2DBC 会获得重大收益,否则我会满足于使用 Spring Data JPA 并使用 subscribeOn 在单独的线程中执行对存储库的调用。
    祝你好运,编码愉快!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-23
      • 1970-01-01
      • 1970-01-01
      • 2016-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多