R2DBC Repository
本章重点介绍了 R2DBC 的 Repository 支持的特性。这基于 使用 Spring Data Repository 中解释的核心 Repository 支持。在阅读本章之前,您应该对其中解释的基本概念有深入的理解。
使用
为了访问存储在关系型数据库中的领域实体,您可以使用我们强大的 Repository 支持,它极大地简化了实现。为此,请为您的 Repository 创建一个接口。考虑以下 Person
类
public class Person {
@Id
private Long id;
private String firstname;
private String lastname;
// … getters and setters omitted
}
以下示例显示了前述 Person
类的 Repository 接口
public interface PersonRepository extends ReactiveCrudRepository<Person, Long> {
// additional custom query methods go here
}
要配置 R2DBC Repository,您可以使用 @EnableR2dbcRepositories
注解。如果未配置基础包,基础设施将扫描带注解的配置类所在的包。以下示例展示了如何使用 Java 配置来配置 Repository
@Configuration
@EnableR2dbcRepositories
class ApplicationConfig extends AbstractR2dbcConfiguration {
@Override
public ConnectionFactory connectionFactory() {
return …
}
}
由于我们的领域 Repository 扩展了 ReactiveCrudRepository
,它提供了响应式 CRUD 操作来访问实体。在 ReactiveCrudRepository
的基础上,还有 ReactiveSortingRepository
,它增加了类似于 PagingAndSortingRepository
的附加排序功能。使用 Repository 实例仅仅是将其依赖注入到客户端即可。因此,您可以使用以下代码检索所有 Person
对象
@ExtendWith(SpringExtension.class)
@ContextConfiguration
class PersonRepositoryTests {
@Autowired
PersonRepository repository;
@Test
void readsAllEntitiesCorrectly() {
repository.findAll()
.as(StepVerifier::create)
.expectNextCount(1)
.verifyComplete();
}
@Test
void readsEntitiesByNameCorrectly() {
repository.findByFirstname("Hello World")
.as(StepVerifier::create)
.expectNextCount(1)
.verifyComplete();
}
}
前面的示例使用了 Spring 的单元测试支持创建了一个应用上下文,它将基于注解的依赖注入执行到测试用例中。在测试方法内部,我们使用 Repository 查询数据库。我们使用 StepVerifier
作为测试辅助工具来验证我们对结果的预期。
结果映射
返回 Interface 或 DTO 投影的查询方法由实际查询产生的结果支持。接口投影通常首先依赖于将结果映射到领域类型,以考虑潜在的 @Column
类型映射,并且实际的投影代理使用可能部分物化的实体来暴露投影数据。
DTO 投影的结果映射取决于实际的查询类型。派生查询使用领域类型来映射结果,Spring Data 仅从领域类型上可用的属性创建 DTO 实例。在您的 DTO 中声明领域类型上不可用的属性是不受支持的。
基于字符串的查询使用不同的方法,因为实际的查询(特别是字段投影)和结果类型声明紧密相关。使用 @Query
注解的查询方法所使用的 DTO 投影将查询结果直接映射到 DTO 类型。领域类型上的字段映射不会被考虑。直接使用 DTO 类型,您的查询方法可以从更动态的投影中受益,这种投影不受领域模型的限制。
使用多个数据库
当使用多个可能不同的数据库时,您的应用程序需要一种不同的配置方法。提供的 AbstractR2dbcConfiguration
支持类假定存在单个 ConnectionFactory
,Dialect
从中派生。也就是说,您需要自己定义一些 bean 来配置 Spring Data R2DBC 以使用多个数据库。
R2DBC Repository 需要 R2dbcEntityOperations
来实现 Repository。一个不使用 AbstractR2dbcConfiguration
的简单 Repository 扫描配置如下所示
@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
允许通过 databaseClientRef
或 entityOperationsRef
进行配置。当连接到同类型的多个数据库时,使用多个 DatabaseClient
bean 会很有用。当使用不同方言的不同数据库系统时,请改用 @EnableR2dbcRepositories
(entityOperationsRef = …) 。