spring-boot - 在 Spring Data R2DBC 中设计一对一和一对多关系

标签 spring-boot spring-data-r2dbc r2dbc spring-data-jdbc

在使用 Spring Data R2DBC 设计一对一和一对多关系时,我正在探索可能的想法。

由于 Spring Data R2DBC 仍然不支持原生关系,因此仍然需要我们自己处理这些关系(与 Spring Data JDBC 不同)。

我想象的是,当涉及到一对一映射时,实现可能如下所示:

@Table("account")
public class Account {
    
    @Id
    private Long id;
    
    @Transient // one-to-one
    private Address address;
    }
@Table("address")
public class Address {
    
    @Id
    private Integer id;
}

而数据库架构将定义如下:

--address
CREATE TABLE address
(
    id                  SERIAL PRIMARY KEY
)
    
--account
CREATE TABLE account
(
    id                     SERIAL PRIMARY KEY,
    address_id             INTEGER REFERENCES address(id)
)

由于 Account 对象是我的聚合根,我想我应该按照 Jens Schaduer 的建议加载 Address 对象:

An aggregate is a cluster of objects that form a unit, which should always be consistent. Also, it should always get persisted (and loaded) together. source: Spring Data JDBC, References, and Aggregates

这让我想到,在像这样的一对一关系的情况下,我实际上应该像这样定义我的 Account 实体:

@Table("account")
public class Account {
    
    @Id
    private Long id;
    
    @Transient // one-to-one
    private Address address;

    @Column("address_id")
    private Integer addressId;
}

然后重新创建完整的 Account 聚合实体和 Address 我会这样写:

@Service
public class AccountServiceImpl implements AccountService {
    
    private final AccountRepository accountRepository;
    private final AddressRepository addressRepository;
    
    public AccountServiceImpl(AccountRepository accountRepository,
                              AddressRepository addressRepository) {
        this.accountRepository = accountRepository;
        this.addressRepository = addressRepository;
    }
    
    @Override
    public Mono<Account> loadAccount(Integer id) {
        return accountRepository.getAccountById(id)
            .flatMap(account ->
                 Mono.just(account)
                 .zipWith(addressRepository.getAddressByAccountId(account.getAddressId()))
                 .map(result -> {
                     result.getT1().setAddress(result.getT2());
                         return result.getT1();
                 })
        );
    }
}

如果不是这种情况,在使用 Spring Data R2DBC 时我还应该如何处理一对一关系?

最佳答案

我认为你的做法是合理的。只有几个问题:

  • 你需要 flatMap -> Mono.just 吗?不能直接用map吗?
  • 我不认为这是一个服务,而是一个存储库(它不是由 Spring Data 直接实现的。
  • 您可以在加载后回调中使用该代码。

关于spring-boot - 在 Spring Data R2DBC 中设计一对一和一对多关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73857930/

相关文章:

java - 无法在目标目录中构建 war 文件 : Failed to delete validation-api-2. 0.1.Final.jar

java - Spring boot @Scheduler 无法在 tomcat 上运行

java - REST API 自动连接服务的远程或本地实现

java - 使用 Spring Data R2DBC 获取嵌套对象

spring-webflux - 连接重用和事务(关系)

将网关连接到服务激活器的 Spring 集成

java - Spring R2DBC 中多对多关系的复杂 ID

java - 如何使用两个不同的驱动程序重用 `testcontainers` 容器?

h2 - Spring R2DBC - 使用 schema.sql 和 ConnectionFactoryInitializer 创建 h2 表时出现 "Table already exists"错误