Spring Data R2DBC 1.0 RC1 版本發佈

發佈 | Mark Paluch | 2019年10月01日 | ...

謹代表團隊和所有貢獻者,我很高興地宣佈 Spring Data R2DBC 1.0 的第一個候選版本已經發佈,並且可以從我們的里程碑儲存庫中取得。此版本包含 60 個問題和提取請求。它將基準升級到 R2DBC 0.8 RC1 和 Spring Data Moore GA。

最值得注意的功能包括

  • 透過 AbstractRoutingConnectionFactory 進行 ConnectionFactory 路由。
  • 透過 ResourceDatabasePopulatorScriptUtils 進行架構初始化的實用程式。
  • 透過 TransactionDefinition 傳播和重置自動提交和隔離級別控制。
  • 支援實體層級轉換器。
  • 用於具體化泛型和協程的 Kotlin 擴展。
  • 新增可插入的機制以註冊 dialects。
  • 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 建立 DatabaseClient,以確定每個訂閱的適當 ConnectionFactory。路由鍵本身會附加到 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 的支援。 有時您可能需要初始化在伺服器上某處運行的實例或嵌入式資料庫。 以下列表顯示如何註冊和配置 ConnectionFactoryInitializer bean 以透過 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 結尾,作為協程方法的指標。

可插入 Dialects

到目前為止,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

Artifact 座標

如果您使用 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 社群中所有即將舉行的活動。

查看全部