# For Maven add: --build maven
$ mn create-app --lang java example --features data-r2dbc,flyway,mysql
Table of Contents
Micronaut R2DBC
Integration with Micronaut and R2DBC
Version: 5.5.0
1 Introduction
This module provides integration between Micronaut and R2DBC.
2 Release History
For this project, you can find a list of releases (with release notes) here:
3 Quick Start
The quickest way to get started is to create a new Micronaut application with Micronaut Launch and choose the data-r2dbc
, mysql
and flyway
features. This can also be done via the Micronaut 2.2 and above CLI:
Or via curl
:
curl
# For Maven add to the URL: &build=maven
$ curl https://launch.micronaut.io/demo.zip?lang=java&features=data-r2dbc,flyway,mysql -o demo.zip && unzip demo.zip -d demo && cd demo
The generated application will use MySQL since we passed the mysql
feature adding dependency on the R2DBC driver for MySQL:
runtimeOnly("dev.miku:r2dbc-mysql")
<dependency>
<groupId>dev.miku</groupId>
<artifactId>r2dbc-mysql</artifactId>
<scope>runtime</scope>
</dependency>
And for flyway the JDBC driver:
runtimeOnly("mysql:mysql-connector-java")
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
To create configurations for other drivers you can select the appropriate feature: oracle , postgres , sqlserver , h2 or mariadb .
|
Now define a SQL script that creates your initial schema in src/main/resources/db/migration
. For example:
V1__create-schema.sql
CREATE TABLE book(id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, title VARCHAR(255), pages INT, author_id BIGINT NOT NULL);
CREATE TABLE author(id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255));
You can now configure your application to connect to the database using src/main/resources/application.yml
which contains the application configuration:
application.yml
flyway: (1)
datasources:
default:
enabled: true
datasources:
default: (2)
url: jdbc:mysql://localhost:3306/mydatabase
r2dbc:
datasources:
default: (3)
url: r2dbc:mysql:///mydatabase
1 | The Flyway configuration ensures the schema migration is applied. See Micronaut Flyway for more information. |
2 | The Flyway configuration needs a JDBC datasource configured, this setting configures one. See Micronaut JDBC for more information. |
3 | The property r2dbc.datasources.default.url is used to configure the default R2DBC ConnectionFactory |
The R2DBC ConnectionFactory object can be injected anywhere in your code with dependency injection.
|
Now define a @MappedEntity
that maps to the author
table defined in the schema:
package example;
import io.micronaut.data.annotation.*;
import io.micronaut.serde.annotation.Serdeable;
@Serdeable
@MappedEntity
public class Author {
@GeneratedValue
@Id
private Long id;
private final String name;
public Author(String name) {
this.name = name;
}
public String getName() {
return name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
package example
import io.micronaut.data.annotation.*
import io.micronaut.serde.annotation.Serdeable
@Serdeable
@MappedEntity
class Author {
@GeneratedValue
@Id
Long id
final String name
Author(String name) {
this.name = name
}
}
package example
import io.micronaut.data.annotation.GeneratedValue
import io.micronaut.data.annotation.Id
import io.micronaut.data.annotation.MappedEntity
import io.micronaut.serde.annotation.Serdeable
@Serdeable
@MappedEntity
data class Author(val name: String) {
@GeneratedValue
@Id
var id: Long? = null
}
And a repository interface to access the database that extends from ReactiveStreamsRepository
:
package example;
import io.micronaut.core.annotation.NonNull;
import io.micronaut.data.model.query.builder.sql.Dialect;
import io.micronaut.data.r2dbc.annotation.R2dbcRepository;
import io.micronaut.data.repository.reactive.ReactiveStreamsCrudRepository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import jakarta.validation.constraints.NotNull;
@R2dbcRepository(dialect = Dialect.MYSQL) // (1)
public interface AuthorRepository extends ReactiveStreamsCrudRepository<Author, Long> {
@NonNull
@Override
Mono<Author> findById(@NonNull @NotNull Long aLong); // (2)
@NonNull
@Override
Flux<Author> findAll();
}
package example
import io.micronaut.core.annotation.NonNull
import io.micronaut.data.model.query.builder.sql.Dialect
import io.micronaut.data.r2dbc.annotation.R2dbcRepository
import io.micronaut.data.repository.reactive.ReactiveStreamsCrudRepository
import reactor.core.publisher.Flux
import reactor.core.publisher.Mono
import jakarta.validation.constraints.NotNull
@R2dbcRepository(dialect = Dialect.MYSQL) // (1)
interface AuthorRepository extends ReactiveStreamsCrudRepository<Author, Long> {
@NonNull
@Override
Mono<Author> findById(@NonNull @NotNull Long aLong) // (2)
@NonNull
@Override
Flux<Author> findAll()
}
package example
import io.micronaut.data.model.query.builder.sql.Dialect
import io.micronaut.data.r2dbc.annotation.R2dbcRepository
import io.micronaut.data.repository.reactive.ReactiveStreamsCrudRepository
import reactor.core.publisher.Flux
import reactor.core.publisher.Mono
import jakarta.validation.constraints.NotNull
@R2dbcRepository(dialect = Dialect.MYSQL) // (1)
interface AuthorRepository : ReactiveStreamsCrudRepository<Author, Long> {
override fun findById(id: @NotNull Long): Mono<Author> // (2)
override fun findAll(): Flux<Author>
}
1 | The @R2dbcRepository annotation can be used to specify the datasource and dialect |
2 | You can override methods from the super interface to specialize the default Publisher return type with a concrete implementation |
You can now inject this interface into controllers and use it to perform R2DBC queries:
package example;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@Controller("/authors")
public class AuthorController {
private final AuthorRepository repository;
public AuthorController(AuthorRepository repository) {
this.repository = repository;
}
@Get
Flux<Author> all() { // (1)
return repository.findAll();
}
@Get("/id")
Mono<Author> get(Long id) { // (2)
return repository.findById(id);
}
}
package example
import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import reactor.core.publisher.Flux
import reactor.core.publisher.Mono
@Controller("/authors")
class AuthorController {
private final AuthorRepository repository
AuthorController(AuthorRepository repository) {
this.repository = repository
}
@Get
Flux<Author> all() { // (1)
return repository.findAll()
}
@Get("/id")
Mono<Author> get(Long id) { // (2)
return repository.findById(id)
}
}
package example
import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import reactor.core.publisher.Flux
import reactor.core.publisher.Mono
@Controller("/authors")
class AuthorController(private val repository: AuthorRepository) {
@Get
fun all(): Flux<Author> { // (1)
return repository.findAll()
}
@Get("/id")
fun get(id: Long): Mono<Author> { // (2)
return repository.findById(id)
}
}
1 | By returning a reactive type that emits many items you can stream data (either Flowable or Flux ) |
2 | By returning a reactive type that emits a single item you return the entire response (either Single or Mono ) |
4 Available Drivers
The following drivers are available as of this writing.
H2
R2DBC Driver:
runtimeOnly("io.r2dbc:r2dbc-h2")
<dependency>
<groupId>io.r2dbc</groupId>
<artifactId>r2dbc-h2</artifactId>
<scope>runtime</scope>
</dependency>
And for Flyway migrations the JDBC driver:
runtimeOnly("com.h2database:h2")
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
MySQL
R2DBC Driver:
runtimeOnly("dev.miku:r2dbc-mysql")
<dependency>
<groupId>dev.miku</groupId>
<artifactId>r2dbc-mysql</artifactId>
<scope>runtime</scope>
</dependency>
And for Flyway migrations the JDBC driver:
runtimeOnly("mysql:mysql-connector-java")
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
MariaDB
R2DBC Driver:
runtimeOnly("org.mariadb:r2dbc-mariadb")
<dependency>
<groupId>org.mariadb</groupId>
<artifactId>r2dbc-mariadb</artifactId>
<scope>runtime</scope>
</dependency>
And for Flyway migrations the JDBC driver:
runtimeOnly("org.mariadb.jdbc:mariadb-java-client")
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<scope>runtime</scope>
</dependency>
Postgresql
R2DBC Driver:
runtimeOnly("org.postgresql:r2dbc-postgresql")
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>r2dbc-postgresql</artifactId>
<scope>runtime</scope>
</dependency>
And for Flyway migrations the JDBC driver:
runtimeOnly("org.postgresql:postgresql")
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
SQL Server
R2DBC Driver:
runtimeOnly("io.r2dbc:r2dbc-mssql")
<dependency>
<groupId>io.r2dbc</groupId>
<artifactId>r2dbc-mssql</artifactId>
<scope>runtime</scope>
</dependency>
And for Flyway migrations the JDBC driver:
runtimeOnly("com.microsoft.sqlserver:mssql-jdbc")
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<scope>runtime</scope>
</dependency>
5 Micronaut Data R2DBC
Micronaut Data builds on this module and provides support for Reactive repositories. See the documentation on Micronaut Data R2DBC for more information and the Quick Start section for a demonstration on how to create an application.
6 Repository
You can find the source code of this project in this repository: