Spring Data R2DBC | Preface
Spring Data R2DBC applies core Spring concepts to solutions that use R2DBC drivers for relational databases. It provides DatabaseClient as a high-level abstraction for storing and retrieving rows.
This document is the reference guide for Spring Data R2DBC support. It explains the concepts and meaning of the R2DBC module and gives a basic overview of Spring and database access.
1. Learning Spring
Spring Data uses core Spring Framework features such as the IoC container, type conversion system, expression language, JMX integration, and DAO exception hierarchy.
You do not need to know every Spring API, but it is important to understand the concepts behind Spring, especially Inversion of Control (IoC), and to be familiar with the IoC container you use.
The core R2DBC support can be used directly without calling IoC services from the Spring container. This is similar to using JdbcTemplate in a standalone way. To use all Spring Data R2DBC features, including repository support, parts of the library must be configured through Spring.
2. What is R2DBC?
R2DBC stands for Reactive Relational Database Connectivity. It is an API specification initiative that defines a reactive API for database driver vendors to access relational databases.
R2DBC was created because non-blocking application stacks are needed to handle concurrency with fewer threads and fewer hardware resources. JDBC is a fully blocking API, so reusing JDBC cannot satisfy that requirement. A ThreadPool can imitate non-blocking behavior only with significant limitations.
Another motivation is that many applications still store data in relational databases. Although some NoSQL vendors provide reactive clients, most projects cannot simply migrate to NoSQL. A common API was therefore needed as a foundation for non-blocking relational database drivers.
3. What is Reactive?
The term reactive refers to programming models built around reacting to changes, availability, and completion signals, such as network components reacting to I/O events or UI controllers reacting to mouse events. Non-blocking work can be considered reactive because the program reacts when work completes or data becomes available rather than waiting by blocking.
Spring also connects reactive programming with non-blocking back pressure. In synchronous imperative code, blocking a call naturally makes the caller wait. In non-blocking code, it is essential to control event speed so that a fast producer does not overwhelm a consumer.
Reactive Streams is a small specification that defines interactions between asynchronous components with back pressure. Its main purpose is to let a subscriber control the rate at which a publisher produces data.
4. Reactive APIs
Reactive Streams is important for interoperability, but it is too low-level for most application APIs. Applications need higher-level functional APIs to compose asynchronous logic.
Project Reactor is the reactive library used by Spring Data R2DBC. It provides Mono for 0..1 values and Flux for 0..N values. Reactor supports non-blocking back pressure and is developed closely with Spring.
Spring Data R2DBC depends on Project Reactor but can interoperate with other reactive libraries through the Reactive Streams specification. Repositories generally accept a generic Publisher as input, adapt it internally to Reactor types, and return either Mono or Flux.
5. Requirements
Spring Data R2DBC 1.x binaries require:
- JDK 8.0 or later
- Spring Framework 5.3.13 or later
- R2DBC Arabba-SR10 or later
6. Additional Help Resources
Learning a new framework is not always easy. For help, use community resources such as Stack Overflow with Spring Data tags. Professional support is also available from companies that support Spring Data and Spring.
7. Following Development
For source repositories, nightly builds, and snapshot artifacts, see the Spring Data R2DBC homepage. You can interact with the community on Stack Overflow, create issues in the Spring Data R2DBC issue tracker, subscribe to the Spring portal, and follow the Spring blog or the Spring Data team.
8. Project Metadata
- Version control: https://github.com/spring-projects/spring-data-r2dbc
- Bug tracker: https://github.com/spring-projects/spring-data-r2dbc/issues
- Release repository: https://repo.spring.io/libs-release
- Milestone repository: https://repo.spring.io/libs-milestone
- Snapshot repository: https://repo.spring.io/libs-snapshot
9. Notable New Features
Spring Data R2DBC 1.3 introduced Query by Example. Version 1.2 moved DatabaseClient to the Spring R2DBC packaged API and added entity callback support, auditing with @EnableR2dbcAuditing, persistence constructor @Value support, and Oracle R2DBC driver support.
Version 1.1 introduced R2dbcEntityTemplate, query derivation, interface projections through DatabaseClient.as(...), and ExecuteFunction and StatementFilterFunction support through DatabaseClient.filter(...).
Version 1.0 upgraded to R2DBC 0.8.0.RELEASE and added initial repository, transaction, dialect, routing, schema initialization, converter, Kotlin extension, and named parameter support.
10. Dependencies
Because individual Spring Data modules start at different times, many modules have different major and minor versions. The easiest way to find compatible versions is to use the Spring Data release train BOM.
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-bom</artifactId>
<version>2021.1.0</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
With the BOM, Spring Data dependencies can be declared without individual versions. Spring Boot also manages Spring Data module versions and can be overridden with the spring-data-releasetrain.version property.
11. Working with Spring Data Repositories
The goal of the Spring Data repository abstraction is to reduce boilerplate code for data access layers. The central interface is Repository, which captures the domain type and ID type. CrudRepository adds common CRUD methods such as save, findById, findAll, count, delete, and existsById.
PagingAndSortingRepository extends CrudRepository and adds methods for sorted and paged access.
public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> {
Iterable<T> findAll(Sort sort);
Page<T> findAll(Pageable pageable);
}
Technology-specific repositories such as JpaRepository or MongoRepository extend these general interfaces and expose features of the underlying persistence technology.