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