El proyecto Conectividad reactiva de bases de datos relacionales (R2DBC) lleva la API de programación reactiva a bases de datos relacionales. io.r2dbc.spi.Connection de R2DBC proporciona un método estándar para tratar con conexiones de bases de datos sin bloqueo. Las conexiones se pasan usando ConnectionFactory, similar a DataSource en jdbc.

La configuración de ConnectionFactory está controlada por propiedades de configuración externas de spring.r2dbc.*. Por ejemplo, podría declarar la siguiente sección en application.properties:

Propiedades
spring.r2dbc.url=r2dbc:postgresql://localhost/test
spring.r2dbc.nombre de usuario=dbuser
spring.r2dbc.password=dbpass
Yaml
spring:
  r2dbc:
    url: "r2dbc:postgresql://localhost/test"
    username: "dbuser"
    password: "dbpass"
No es necesario especificar un nombre de clase para el controlador porque Spring Boot obtiene el controlador mediante el descubrimiento de la fábrica de conexiones R2DBC.
Como mínimo, se debe proporcionar una URL. La información especificada en la URL tiene prioridad sobre las propiedades individuales, es decir, name, username, password y parámetros de agrupación.

Para personalizar las conexiones creadas por ConnectionFactory, es decir, para establecer ciertos parámetros que no desea (o no puede) configurar en la configuración de su base de datos central, puede utilizar un anotación @Bean bean ConnectionFactoryOptionsBuilderCustomizer. El siguiente ejemplo muestra cómo anular manualmente el puerto de la base de datos mientras el resto de las configuraciones se toman de la configuración de la aplicación:

Java
import io.r2dbc.spi.ConnectionFactoryOptions;
import org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryOptionsBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class MyR2dbcConfiguration {
    @Bean
    public ConnectionFactoryOptionsBuilderCustomizer connectionFactoryPortCustomizer() {
        return (builder) -> builder.option(ConnectionFactoryOptions.PORT, 5432);
    }
}
Kotlin
importar io.r2dbc.spi.ConnectionFactoryOptions
importar org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryOptionsBuilderCustomizer
importar org.springframework.context.annotation.Bean
importar org.springframework.context.annotation.Configuration
@Configuration(proxyBeanMethods = false)
clase Configuración MyR2dbc {
    @Frijol
    divertido ConnectionFactoryPortCustomizer(): ConnectionFactoryOptionsBuilderCustomizer {
        return ConnectionFactoryOptionsBuilderCustomizer { constructor ->
            opción.constructor(ConnectionFactoryOptions.PORT, 5432)
        }
    }
}

Los siguientes ejemplos muestran cómo configurar algunos parámetros de conexión PostgreSQL:

Java
import java.util.HashMap;
import java.util.Map;
import io.r2dbc.postgresql.PostgresqlConnectionFactoryProvider;
import org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryOptionsBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class MyPostgresR2dbcConfiguration {
    @Bean
    public ConnectionFactoryOptionsBuilderCustomizer postgresCustomizer() {
        Map<String, String> options = new HashMap<>();
        options.put("lock_timeout", "30s");
        options.put("statement_timeout", "60s");
        return (builder) -> builder.option(PostgresqlConnectionFactoryProvider.OPTIONS, options);
    }
}
Kotlin
import io.r2dbc.postgresql.PostgresqlConnectionFactoryProvider
import org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryOptionsBuilderCustomizer
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@Configuration(proxyBeanMethods = false)
class MyPostgresR2dbcConfiguration {
    @Bean
    fun postgresCustomizer(): ConnectionFactoryOptionsBuilderCustomizer {
        val options: MutableMap<String, String> = HashMap()
        options["lock_timeout"] = "30s"
        options["statement_timeout"] = "60s"
        return ConnectionFactoryOptionsBuilderCustomizer { builder ->
            builder.option(PostgresqlConnectionFactoryProvider.OPTIONS, options)
        }
    }
}

Si hay presente un bean ConnectionFactory, la configuración automática normal para DataSource desde JDBC está deshabilitada. Si necesita conservar la configuración automática para DataSource de JDBC y se siente cómodo con el riesgo de utilizar una API JDBC de bloqueo en una aplicación reactiva, agregue @Import(DataSourceAutoConfiguration.class) a la clase marcada con la anotación @Configuration, en tu aplicación para volver a habilitarla.

Soporte para bases de datos integradas

Al igual que la compatibilidad con JDBC, el marco Spring Boot puede configurar automáticamente la base de datos integrada para uso reactivo. No es necesario que proporcione ninguna URL de conexión. Solo necesita agregar una dependencia de compilación a la base de datos integrada que desea usar, como se muestra en el siguiente ejemplo:

<dependency>
    <groupId>io.r2dbc</groupId>
    <artifactId>r2dbc-h2</artifactId>
    <scope>runtime</scope>
</dependency>

Si utiliza esta función en sus pruebas, puede observar que todo el conjunto de pruebas reutiliza la misma base de datos, independientemente del número de contextos de aplicación que utilice. Si necesita asegurarse de que cada contexto tenga una base de datos integrada independiente, debe establecer spring.r2dbc.generate-unique-name en true.

Usando el cliente de base de datos

El bean DatabaseClient es autoconfigurable, pero puede vincularlo mediante la anotación @Autowire directamente a sus propios beans, como se muestra en el siguiente ejemplo:

Java
import java.util.Map;
import reactor.core.publisher.Flux;
import org.springframework.r2dbc.core.DatabaseClient;
import org.springframework.stereotype.Component;
@Component
public class MyBean {
    private final DatabaseClient databaseClient;
    public MyBean(DatabaseClient databaseClient) {
        this.databaseClient = databaseClient;
    }
 // ...
 public Flux<Map<String, Object>> someMethod() {
        return this.databaseClient.sql("select * from user").fetch().all();
    }
}
Kotlin
import org.springframework.r2dbc.core.DatabaseClient
import org.springframework.stereotype.Component
import reactor.core.publisher.Flux
@Component
class MyBean(private val databaseClient: DatabaseClient) {
 // ...
 fun someMethod(): Flux<Map<String, Any>> {
        return databaseClient.sql("select * from user").fetch().all()
    }
}

Repositorios Spring Data R2DBC

Los repositorios Spring Data R2DBC son interfaces que se pueden definir para acceder a los datos. Las consultas se crean automáticamente en función de los nombres de los métodos. Por ejemplo, la interfaz CityRepository podría declarar un método findAllByState(String state) para buscar todas las ciudades en un estado determinado.

Para consultas más complejas, puede anotar el método utilizando la anotación Query de Spring Data.

Los repositorios de Spring Data normalmente se amplían utilizando las interfaces Repository o CrudRepository. Si utiliza la configuración automática, los repositorios se buscan desde el paquete que contiene la clase de configuración principal (la que está anotada con @EnableAutoConfiguration o @SpringBootApplication) y hacia abajo en la jerarquía.

El siguiente ejemplo muestra una definición de interfaz típica para interactuar con un repositorio de Spring Data:

Java
import reactor.core.publisher.Mono;
import org.springframework.data.repository.Repository;
public interface CityRepository extends Repository<City, Long> {
    Mono<City> findByNameAndStateAllIgnoringCase(String name, String state);
}
Kotlin
import org.springframework.data.repository.Repository
import reactor.core.publisher.Mono
interface CityRepository : Repository<City?, Long?> {
    fun findByNameAndStateAllIgnoringCase(name: String?, state: String?): Mono<City?>?
}