如何在以前使用 JPA 的项目中使用 R2DBC 实现 OneToMany、ManyToOne 和 ManyToMany?

How to implement OneToMany, ManyToOne and ManyToMany with R2DBC in a project which previously used JPA?

我必须重新实现一些后端服务,主要要求之一是使整个流程具有反应性。以前,服务将休眠与 PostgreSQL 结合使用,因此上述连接由框架提供。

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

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

我正在调查类似的事情并得出相同的结论 (1),因为 R2DBC 中不支持关系。 为了迁移一对多关系,我首先将包含 "many" 实体的集合创建到 "one" 实体中的 @Transient。 持久化 "one" 实体是使用反应序列中的以下步骤完成的:

  1. 保留 "many" 个实体。这是为了能够在 "one" 实体中更新这些,以便为 "many" 实体分配 ID。
  2. 保留 "one" 实体。
  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 并在单独的线程中执行对存储库的调用,使用订阅。
祝你好运,编码愉快!