R2DBC Repositories

  • 使用 ReactiveCrudRepository 轻松访问关系型数据库中的实体

  • 复杂存储库支持,允许创建查询方法和自定义投影

  • 支持反应式 CRUD 操作,包括分页和排序

  • 使用 DTO 投影将查询结果映射到接口或 DTO

  • 为处理多个数据库提供配置选项

本章指出了 R2DBC 存储库支持的特殊性。这是在 Working with Spring Data Repositories中解释的核心存储库支持的基础上构建的。在阅读本章之前,你应该对那里解释的基本概念有深入的了解。

Usage

若要访问存储在关系型数据库中的域实体,您可以使用我们复杂的存储库支持,这极大地简化了实现。为此,请为您的存储库创建一个界面。考虑以下 Person 类:

Sample Person entity
public class Person {

  @Id
  private Long id;
  private String firstname;
  private String lastname;

  // … getters and setters omitted
}

以下示例显示了前面 Person 类的存储库界面:

Basic repository interface to persist Person entities
public interface PersonRepository extends ReactiveCrudRepository<Person, Long> {

  // additional custom query methods go here
}

若要配置 R2DBC 存储库,您可以使用 @EnableR2dbcRepositories 注释。如果未配置基本包,基础结构将扫描带注释的配置类的包。以下示例演示如何将 Java 配置用于存储库:

Java configuration for repositories
@Configuration
@EnableR2dbcRepositories
class ApplicationConfig extends AbstractR2dbcConfiguration {

  @Override
  public ConnectionFactory connectionFactory() {
    return …
  }
}

由于我们的域存储库扩展了 ReactiveCrudRepository ,因此它为您提供了反应式 CRUD 操作来访问实体。在 ReactiveCrudRepository 之上,还有 ReactiveSortingRepository ,它添加了类似于 PagingAndSortingRepository 的其他排序功能。只需依赖注入它到客户端,即可使用存储库实例。因此,您可以使用以下代码检索所有 Person 对象:

Paging access to Person entities
link:example$r2dbc/PersonRepositoryTests.java[role=include]

前面的示例使用 Spring 的单元测试支持创建应用程序上下文,该支持对测试用例执行基于注释的依赖注入。在测试方法中,我们使用存储库查询数据库。我们使用 StepVerifier 作为测试辅助工具,以根据结果验证我们的预期。

Result Mapping

返回接口或 DTO 投影的查询方法由实际查询生成的结果支持。接口投影通常首先依赖于将结果映射到域类型以考虑潜在的 @Column 类型映射,而实际投影代理使用潜在的部分物化实体来公开投影数据。

DTO 投影的结果映射取决于实际的查询类型。派生查询使用域类型映射结果,而 Spring Data 仅从域类型上可用的属性创建 DTO 实例。不支持在 DTO 中声明域类型上不可用的属性。

基于字符串的查询使用不同的方法,因为实际查询(特别是字段投影)和结果类型声明紧密相连。用于 @Query 注释的查询方法的 DTO 投影直接将查询结果映射到 DTO 类型。不考虑域类型上的字段映射。通过直接使用 DTO 类型,您的查询方法可以受益于不受域模型限制的更动态投影。

Working with multiple Databases

在处理多个可能不同的数据库时,您的应用程序将需要不同的配置方法。提供的 AbstractR2dbcConfiguration 支持类假定有一个 ConnectionFactory ,从中可以导出 Dialect 。也就是说,您需要自己定义一些 Bean,以配置 Spring Data R2DBC 以便与多个数据库一起使用。

R2DBC 存储库需要 R2dbcEntityOperations 来实现存储库。用于扫描存储库而无需使用 AbstractR2dbcConfiguration 的简单配置如下所示:

@Configuration
@EnableR2dbcRepositories(basePackages = "com.acme.mysql", entityOperationsRef = "mysqlR2dbcEntityOperations")
static class MySQLConfiguration {

    @Bean
    @Qualifier("mysql")
    public ConnectionFactory mysqlConnectionFactory() {
        return …
    }

    @Bean
    public R2dbcEntityOperations mysqlR2dbcEntityOperations(@Qualifier("mysql") ConnectionFactory connectionFactory) {

        DatabaseClient databaseClient = DatabaseClient.create(connectionFactory);

        return new R2dbcEntityTemplate(databaseClient, MySqlDialect.INSTANCE);
    }
}

请注意, @EnableR2dbcRepositories 允许通过 databaseClientRefentityOperationsRef 进行配置。当连接到同一类型的多个数据库时,使用各种 DatabaseClient Bean 很有用。当使用方言不同的不同数据库系统时,请使用 @EnableR2dbcRepositories(entityOperationsRef = …)` 。