Spring Data R2DBC 1.0 RC1 发布

发布 | Mark Paluch | 2019年10月1日 | ...

我代表团队和所有做出贡献的人员,高兴地宣布 Spring Data R2DBC 1.0 的第一个候选版本已发布,可从我们的里程碑存储库获取。此版本包含 60 个问题和拉取请求。它将其基线升级到 R2DBC 0.8 RC1 和 Spring Data Moore GA。

最值得注意的功能包括:

  • 通过AbstractRoutingConnectionFactory进行ConnectionFactory路由。
  • 通过ResourceDatabasePopulatorScriptUtils进行模式初始化的实用程序。
  • 通过TransactionDefinition传播和重置自动提交和隔离级别控制。
  • 支持实体级转换器。
  • Kotlin 扩展,用于具现化泛型和协程。
  • 添加可插拔机制来注册方言。
  • API 细化。

ConnectionFactory 路由

对于每个操作,DatabaseClient 从用于创建 DatabaseClientConnectionFactory 获取一个 Connection

其基本思想是路由ConnectionFactory充当中间体——而“真实”的ConnectionFactory是基于查找键在运行时动态确定的。一个潜在的用例是通过使用指向单独数据库的多个ConnectionFactory实例来满足多租户需求。为了让路由ConnectionFactory确定要使用哪个ConnectionFactory,它需要上下文信息。Spring Data R2DBC 带有一个AbstractRoutingConnectionFactory,它可以返回一个查找键,该键用于查找正确的ConnectionFactory

响应式流可以通过使用 Project Reactor 的Context将上下文信息附加到订阅。

路由ConnectionFactory的示例实现可能如下所示:

class RoutingConnectionFactory extends AbstractRoutingConnectionFactory {

    public static final String ROUTING_KEY = "routing-key";

    @Override
    protected Mono<Object> determineCurrentLookupKey() {
        return Mono.subscriberContext().filter(it -> it.hasKey(ROUTING_KEY)).map(it -> it.get(ROUTING_KEY));
    }
}

以下清单显示了如何初始化查找键和目标ConnectionFactory之间的映射的连接工厂。

RoutingConnectionFactory connectionFactory = new RoutingConnectionFactory();
Map<String, ConnectionFactory> factories = new HashMap<>();
factories.put("customer1", …);
factories.put("customer2", …);
connectionFactory.setTargetConnectionFactories(factories);
connectionFactory.afterPropertiesSet();

您可以通过使用路由ConnectionFactory为每个订阅确定合适的ConnectionFactory来创建DatabaseClient。路由键本身附加到Context中,并由RoutingConnectionFactory进行评估,如下所示:

DatabaseClient client = DatabaseClient.create(connectionFactory);

Context routingContext = Context.of(ROUTING_KEY, "customer1");

Flux<User> users = client.execute("SELECT first_name, last_name FROM user")
                .as(User.class)
                .fetch()
                .all()
                .subscriberContext(routingContext);

模式初始化

org.springframework.data.r2dbc.connectionfactory.init包提供了初始化现有ConnectionFactory的支持。您有时可能需要初始化在某个服务器上运行的实例或嵌入式数据库。以下清单显示了如何注册和配置ConnectionFactoryInitializerbean以通过ConnectionFactory初始化数据库。

@Configuration
public class InitializerConfiguration {

  @Bean
  public ConnectionFactoryInitializer initializer(ConnectionFactory connectionFactory) {

    ConnectionFactoryInitializer initializer = new ConnectionFactoryInitializer();
    initializer.setConnectionFactory(connectionFactory);

    CompositeDatabasePopulator populator = new CompositeDatabasePopulator();
    populator.addPopulators(new ResourceDatabasePopulator(new ClassPathResource("com/foo/sql/db-schema.sql")));
    populator.addPopulators(new ResourceDatabasePopulator(new ClassPathResource("com/foo/sql/test-data1.sql")));
    initializer.setDatabasePopulator(populator);

    return initializer;
  }
}

此初始化支持由 Spring Boot R2DBC 自动配置使用,以将schema.sqldata.sql应用于配置的ConnectionFactory

Kotlin 扩展

此版本附带 Kotlin 扩展,用于在使用 Kotlin 开发应用程序时习惯性地使用 Spring Data R2DBC。

Spring Data R2DBC 提供以下扩展:

  • DatabaseClientCriteria的具现化泛型支持
  • DatabaseClient的 Kotlin 协程支持

要检索 Java 中的User对象列表,通常会编写以下代码:

Flux<User> characters = client.select().from(User.class).fetch().all();

使用 Kotlin 和 Spring Data 扩展,您可以改为编写以下代码:

val users =  client.select().from<User>().fetch().all()

Kotlin 协程是 Kotlin 轻量级线程,允许以命令式风格编写非阻塞代码。Spring Data R2DBC 的协程扩展利用响应式基础架构来公开可以suspend的函数,并将Flux结果桥接到 Kotlin 的Flow类型。

以下示例显示了使用 Spring Framework 的TransactionalOperator以原子方式插入两行的协程用法:

operator.executeAndAwait {
  client.execute("INSERT INTO person VALUES(:first_name, :last_name)")
        .bind("first_name", "John")
        .bind("last_name", "Doe")
        .await()
  client.execute("INSERT INTO person_events VALUES(:first_name, :last_name, :event_type)")
        .bind("first_name", "John")
        .bind("last_name", "Doe")
        .bind("event_type", "CREATED")
        .await()
}

请注意,大多数suspend方法以await结尾,作为协程方法的指示符。

可插拔方言

目前,R2DBC 驱动程序生态系统仅包含少数几个已知的驱动程序,但驱动程序的数量正在增长。为了实现与其他驱动程序的无缝集成,Spring Data R2DBC 公开了一个用于R2dbcDialect注册的扩展点。Spring Data R2DBC 可以通过注册一个通过 Spring 的META-INF/spring.factories机制实现org.springframework.data.r2dbc.dialect.DialectResolver$R2dbcDialectProvider的类来自动发现R2dbcDialect。以下清单显示了如何操作:

public class MyDialectProvider implements DialectResolver.R2dbcDialectProvider {

    @Override
    public Optional<R2dbcDialect> getDialect(ConnectionFactory connectionFactory) {

        if (connectionFactory.getMetadata().getName().equals("my-dastabase")) {
            return Optional.of(…);
        }
        return Optional.empty();
    }
}

spring.factories

org.springframework.data.r2dbc.dialect.DialectResolver$R2dbcDialectProvider=com.example.MyDialectProvider

构件坐标

如果您使用 Maven,请将以下几行添加到您的pom.xml文件中以升级到 Spring Data R2DBC 1.0 RC1:

<dependencies>
  <dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-r2dbc</artifactId>
    <version>1.0.0.RC1</version>
  </dependency>
</dependencies>

<!-- R2DBC 0.8.0.RC1 required -->
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>io.r2dbc</groupId>
      <artifactId>r2dbc-bom</artifactId>
      <version>Arabba-RC1</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

<repositories>
  <repository>
    <id>spring-milestone</id>
    <url>https://repo.spring.io/milestone</url>
  </repository>
</repositories>

后续步骤

R2DBC 0.8.0 RC1 最近发布,我们预计今年晚些时候将发布 GA 版本。我们正在努力发布 Spring Data R2DBC 1.0 GA 版本,并在 R2DBC 本身发布 GA 后发布下一个版本。我们的待办事项列表包含一系列增强功能,例如查询派生、乐观锁以及允许查询拦截在执行之前更改绑定和 SQL 语句。

最后,以下是变更日志、GitHub 存储库和文档的链接:

获取 Spring 新闻通讯

通过 Spring 新闻通讯保持联系

订阅

领先一步

VMware 提供培训和认证,以加快您的进度。

了解更多

获得支持

Tanzu Spring在一个简单的订阅中提供对 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件。

了解更多

即将举行的活动

查看 Spring 社区中所有即将举行的活动。

查看全部