Skip to content

gudzpoz/r2dbc-jdbc

Repository files navigation

Reactive Relational Database Connectivity JDBC Implementation

Maven Central Sonatype Nexus (Snapshots) GitHub

Build and Publish Test Code Coverage

This project contains a simplistic Java Database Connectivity (JDBC) implementation of the R2DBC SPI. This implementation is not intended to be used directly, but rather to be used as the backing implementation for a humane client library.

As for Spring Data, this library provides a R2dbcDialectProvider. You may simply set spring.r2dbc.url accordingly in your application.yml/properties and things should work out of the box.

It requires Java 9.

Status

It is a toy project, and I promise there will be bugs.

Wait, what?

JDBC Connections                                Reactive
     /|\                                         Access
      |                                             |
|------------|  Input Jobs (SemiBlockingQueue)     \|/
|    The     |  <--------------------------- R2dbcConnections
|            |
|  worker(s) |  --------------------------->   Dispatcher
|------------|       (SemiBlockingQueue)            |
                           Output                   |
                                                   \|/
              Executing callbacks in Schedulers.parallel()

Why?

R2DBC H2 is not that non-blocking. This library, as is shown in the above diagram, actually simulates the regular TCP Client-Server connection to provider reactive access.

For big databases like MariaDB or PostgreSQL, you might as well go to Drivers to find a better SPI. However, if you want reactivity for some embedded databases like H2, Derby or HSQLDB, maybe you can have a go with this.

Usage

Just follow the guide on R2DBC.

From Maven Central

Maven Central

Maven

Using directly?

<dependency>
  <groupId>party.iroiro</groupId>
  <artifactId>r2dbc-jdbc</artifactId>
  <version>0.3.1</version>
</dependency>
Gradle

Using directly?

implementation 'party.iroiro:r2dbc-jdbc:0.3.1'

Use with Spring Data

Maven
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-r2dbc</artifactId>
</dependency>
<dependency>
  <groupId>party.iroiro</groupId>
  <artifactId>r2dbc-jdbc</artifactId>
  <version>0.3.1</version>
  <scope>runtime</scope>
</dependency>
Gradle
implementation 'org.springframework.boot:spring-boot-starter-data-r2dbc'
runtimeOnly 'party.iroiro:r2dbc-jdbc:0.3.1'

Spring Data requires a R2dbcDialectProvider to map repository operations to SQLs. Since different databases may differ in SQL grammar, you may set one matching your database with, for example:

System.setProperty("j2dialect", "org.springframework.data.r2dbc.dialect.H2Dialect");

Currently, available dialects in Spring Data Reactive are:

  • org.springframework.data.r2dbc.dialect.H2Dialect
  • org.springframework.data.r2dbc.dialect.PostgresDialect
  • org.springframework.data.r2dbc.dialect.MySqlDialect
  • org.springframework.data.r2dbc.dialect.OracleDialect
  • org.springframework.data.r2dbc.dialect.SqlServerDialect

Passing JDBC urls

Note that you cannot pass a raw JDBC url directly. With R2DBC API, the call might look like this:

import io.r2dbc.spi.ConnectionFactories;

class Main {
    void test() {
        // String
        ConnectionFactories.get(
                "r2dbc:r2jdbc:h2~mem:///test"
        );
        // ConnectionFactoryOptions is more friendly
        ConnectionFactories.get(
                ConnectionFactoryOptions.builder()
                        .option(ConnectionFactoryOptions.PROTOCOL, "r2dbc")
                        .option(ConnectionFactoryOptions.DATABASE, "r2jdbc")
                        .option(JdbcConnectionFactoryProvider.URL, "jdbc:h2:mem:test")
                        .build());
    }
}

We accept some extra options. All are optional.

OptionExplained

JdbcConnectionFactoryProvider.URL

Example: r2dbc:r2jdbc:h2:///?j2url=jdbc:h2:mem:test

Used directly as JDBC url

Default: Infer from R2DBC url

JdbcConnectionFactoryProvider.FORWARD

Example: r2dbc:r2jdbc:h2:///test?CIPHER=AES&j2forward=CIPHER

What R2DBC options to forward to JDBC (comma separated).

Default: None

JdbcConnectionFactoryProvider.CODEC

Example: r2dbc:r2jdbc:h2:///test?j2codec=party.iroiro.r2jdbc.codecs.DefaultCodec

Name of a class converting JDBC types into regular Java types (used by the worker).

Default: Built-in

JdbcConnectionFactoryProvider.CONV

Example: r2dbc:r2jdbc:h2:///test?j2conv=party.iroiro.r2jdbc.codecs.DefaultConverter

Name of a class converting between Java types.

Default: Built-in

License

I am borrowing tests from R2DBC H2, which is licensed under Apache License 2.0.

Licensed under the Apache License Version 2.0