0
# R2DBC Container Management
1
2
Reactive database access support for MariaDB containers using R2DBC drivers. Enables non-blocking database operations with full container lifecycle integration for reactive applications and testing scenarios.
3
4
## Capabilities
5
6
### R2DBC Container Wrapper
7
8
Wraps a MariaDB container to provide R2DBC connectivity and connection factory configuration.
9
10
```java { .api }
11
/**
12
* R2DBC wrapper for MariaDB containers supporting reactive database access
13
* Delegates Startable methods to the underlying MariaDB container
14
*/
15
@RequiredArgsConstructor
16
public class MariaDBR2DBCDatabaseContainer implements R2DBCDatabaseContainer {
17
18
/**
19
* Creates connection factory options from a MariaDB container
20
* @param container MariaDB container instance
21
* @return Configured ConnectionFactoryOptions for R2DBC
22
*/
23
public static ConnectionFactoryOptions getOptions(MariaDBContainer<?> container);
24
25
/**
26
* Configures connection options with container connection details
27
* @param options Base connection factory options
28
* @return Options configured with host, port, database, and credentials
29
*/
30
public ConnectionFactoryOptions configure(ConnectionFactoryOptions options);
31
}
32
```
33
34
**Usage Examples:**
35
36
```java
37
import org.testcontainers.containers.MariaDBContainer;
38
import org.testcontainers.containers.MariaDBR2DBCDatabaseContainer;
39
import io.r2dbc.spi.ConnectionFactory;
40
import io.r2dbc.spi.ConnectionFactories;
41
import io.r2dbc.spi.ConnectionFactoryOptions;
42
43
// Create MariaDB container and R2DBC wrapper
44
MariaDBContainer<?> mariadbContainer = new MariaDBContainer<>("mariadb:10.3.39")
45
.withDatabaseName("reactive_db")
46
.withUsername("r2dbc_user")
47
.withPassword("r2dbc_pass");
48
49
MariaDBR2DBCDatabaseContainer r2dbcContainer = new MariaDBR2DBCDatabaseContainer(mariadbContainer);
50
51
// Start the container
52
r2dbcContainer.start();
53
54
// Get R2DBC connection factory options
55
ConnectionFactoryOptions options = MariaDBR2DBCDatabaseContainer.getOptions(mariadbContainer);
56
57
// Create connection factory
58
ConnectionFactory connectionFactory = ConnectionFactories.get(options);
59
60
// Use with reactive code
61
Mono<Void> result = Mono.from(connectionFactory.create())
62
.flatMap(connection ->
63
Mono.from(connection.createStatement("SELECT 1").execute())
64
.flatMap(result -> Mono.from(result.map((row, metadata) -> row.get(0))))
65
.doFinally(signalType -> connection.close())
66
);
67
```
68
69
### R2DBC Container Provider
70
71
Factory for creating R2DBC MariaDB containers from connection factory options, enabling declarative container management.
72
73
```java { .api }
74
/**
75
* Provider for creating R2DBC MariaDB containers from connection factory options
76
*/
77
public class MariaDBR2DBCDatabaseContainerProvider implements R2DBCDatabaseContainerProvider {
78
79
/**
80
* The R2DBC driver identifier for MariaDB (package-private constant)
81
* Value: "mariadb"
82
*/
83
// Note: DRIVER constant is package-private, not part of public API
84
85
/**
86
* Checks if this provider supports the connection options
87
* @param options Connection factory options to check
88
* @return true if driver is "mariadb"
89
*/
90
public boolean supports(ConnectionFactoryOptions options);
91
92
/**
93
* Creates R2DBC container from connection options
94
* @param options Connection factory options specifying database and configuration
95
* @return MariaDBR2DBCDatabaseContainer configured from options
96
*/
97
public R2DBCDatabaseContainer createContainer(ConnectionFactoryOptions options);
98
99
/**
100
* Returns connection metadata with default user/password if not specified
101
* @param options Connection factory options
102
* @return Connection metadata with defaults applied
103
*/
104
@Nullable
105
public ConnectionFactoryMetadata getMetadata(ConnectionFactoryOptions options);
106
}
107
```
108
109
**Usage Examples:**
110
111
```java
112
import io.r2dbc.spi.ConnectionFactoryOptions;
113
import org.testcontainers.containers.MariaDBR2DBCDatabaseContainerProvider;
114
import org.testcontainers.r2dbc.R2DBCDatabaseContainer;
115
116
// Create container from connection options
117
ConnectionFactoryOptions options = ConnectionFactoryOptions.builder()
118
.option(ConnectionFactoryOptions.DRIVER, "mariadb")
119
.option(ConnectionFactoryOptions.DATABASE, "test_reactive")
120
.option(IMAGE_TAG_OPTION, "10.3.39")
121
.option(REUSABLE_OPTION, true)
122
.build();
123
124
MariaDBR2DBCDatabaseContainerProvider provider = new MariaDBR2DBCDatabaseContainerProvider();
125
126
if (provider.supports(options)) {
127
R2DBCDatabaseContainer container = provider.createContainer(options);
128
container.start();
129
130
// Get configured connection options
131
ConnectionFactoryOptions configuredOptions = container.configure(options);
132
}
133
```
134
135
### R2DBC URL-based Container Creation
136
137
Automatic container creation from R2DBC URL patterns for seamless integration with R2DBC libraries.
138
139
```java { .api }
140
// R2DBC URL patterns supported:
141
// r2dbc:tc:mariadb:///databasename?TC_IMAGE_TAG=version
142
// r2dbc:tc:mariadb:///databasename?TC_IMAGE_TAG=version&REUSABLE=true
143
```
144
145
**Usage Examples:**
146
147
```java
148
import io.r2dbc.spi.ConnectionFactories;
149
import io.r2dbc.spi.ConnectionFactory;
150
151
// Automatic container creation from R2DBC URL
152
String r2dbcUrl = "r2dbc:tc:mariadb:///testdb?TC_IMAGE_TAG=10.3.39";
153
ConnectionFactory connectionFactory = ConnectionFactories.get(r2dbcUrl);
154
155
// Container is automatically created, started, and managed
156
Flux<Integer> results = Flux.usingWhen(
157
connectionFactory.create(),
158
connection -> Flux.from(connection.createStatement("SELECT 1").execute())
159
.flatMap(result -> result.map((row, metadata) -> row.get(0, Integer.class))),
160
Connection::close
161
);
162
163
// Use in reactive streams
164
results.subscribe(value -> System.out.println("Result: " + value));
165
```
166
167
### Connection Factory Configuration
168
169
Configures R2DBC connection factory options with container connection details.
170
171
```java { .api }
172
/**
173
* Connection factory options configuration
174
* Maps container connection details to R2DBC connection options
175
*/
176
public ConnectionFactoryOptions configure(ConnectionFactoryOptions options) {
177
return options.mutate()
178
.option(ConnectionFactoryOptions.HOST, container.getHost())
179
.option(ConnectionFactoryOptions.PORT, container.getMappedPort(MariaDBContainer.MARIADB_PORT))
180
.option(ConnectionFactoryOptions.DATABASE, container.getDatabaseName())
181
.option(ConnectionFactoryOptions.USER, container.getUsername())
182
.option(ConnectionFactoryOptions.PASSWORD, container.getPassword())
183
.build();
184
}
185
```
186
187
**Usage Examples:**
188
189
```java
190
// Manual configuration of connection factory options
191
MariaDBContainer<?> container = new MariaDBContainer<>("mariadb:10.3.39")
192
.withDatabaseName("r2dbc_test")
193
.withUsername("reactive_user")
194
.withPassword("reactive_pass");
195
196
container.start();
197
198
// Base options
199
ConnectionFactoryOptions baseOptions = ConnectionFactoryOptions.builder()
200
.option(ConnectionFactoryOptions.DRIVER, "mariadb")
201
.build();
202
203
// Configure with container details
204
MariaDBR2DBCDatabaseContainer r2dbcContainer = new MariaDBR2DBCDatabaseContainer(container);
205
ConnectionFactoryOptions configuredOptions = r2dbcContainer.configure(baseOptions);
206
207
// Create connection factory
208
ConnectionFactory factory = ConnectionFactories.get(configuredOptions);
209
```
210
211
## R2DBC Integration Patterns
212
213
### Spring Data R2DBC Configuration
214
215
```java
216
@TestConfiguration
217
public class R2DBCTestConfiguration {
218
219
@Container
220
static MariaDBContainer<?> mariadb = new MariaDBContainer<>("mariadb:10.3.39");
221
222
@Bean
223
@Primary
224
public ConnectionFactory connectionFactory() {
225
return ConnectionFactories.get(MariaDBR2DBCDatabaseContainer.getOptions(mariadb));
226
}
227
228
@Bean
229
public R2dbcEntityTemplate r2dbcEntityTemplate(ConnectionFactory connectionFactory) {
230
return new R2dbcEntityTemplate(connectionFactory);
231
}
232
}
233
```
234
235
### Reactive Testing with JUnit 5
236
237
```java
238
@Testcontainers
239
class ReactiveMariaDBTest {
240
241
@Container
242
static MariaDBContainer<?> mariadb = new MariaDBContainer<>("mariadb:10.3.39")
243
.withDatabaseName("reactive_test");
244
245
private ConnectionFactory connectionFactory;
246
247
@BeforeEach
248
void setUp() {
249
connectionFactory = ConnectionFactories.get(
250
MariaDBR2DBCDatabaseContainer.getOptions(mariadb)
251
);
252
}
253
254
@Test
255
void testReactiveQuery() {
256
StepVerifier.create(
257
Mono.from(connectionFactory.create())
258
.flatMap(connection ->
259
Mono.from(connection.createStatement("SELECT 42").execute())
260
.flatMap(result -> Mono.from(result.map((row, metadata) ->
261
row.get(0, Integer.class))))
262
.doFinally(signalType -> connection.close())
263
)
264
)
265
.expectNext(42)
266
.verifyComplete();
267
}
268
}
269
```
270
271
## Dependencies
272
273
For R2DBC support, include these dependencies:
274
275
```xml
276
<!-- Maven -->
277
<dependency>
278
<groupId>org.testcontainers</groupId>
279
<artifactId>r2dbc</artifactId>
280
<version>1.21.3</version>
281
<scope>test</scope>
282
</dependency>
283
<dependency>
284
<groupId>org.mariadb</groupId>
285
<artifactId>r2dbc-mariadb</artifactId>
286
<version>1.0.3</version>
287
<scope>test</scope>
288
</dependency>
289
```
290
291
```groovy
292
// Gradle
293
testImplementation 'org.testcontainers:r2dbc:1.21.3'
294
testRuntimeOnly 'org.mariadb:r2dbc-mariadb:1.0.3'
295
```
296
297
## Types
298
299
```java { .api }
300
import io.r2dbc.spi.ConnectionFactoryOptions;
301
import io.r2dbc.spi.ConnectionFactoryMetadata;
302
import org.testcontainers.r2dbc.R2DBCDatabaseContainer;
303
import org.testcontainers.r2dbc.R2DBCDatabaseContainerProvider;
304
import org.testcontainers.lifecycle.Startable;
305
306
// Standard R2DBC connection options
307
ConnectionFactoryOptions.DRIVER // "mariadb"
308
ConnectionFactoryOptions.HOST // Container host
309
ConnectionFactoryOptions.PORT // Mapped port (3306)
310
ConnectionFactoryOptions.DATABASE // Database name
311
ConnectionFactoryOptions.USER // Username
312
ConnectionFactoryOptions.PASSWORD // Password
313
314
// Testcontainers-specific options
315
IMAGE_TAG_OPTION // Docker image tag
316
REUSABLE_OPTION // Container reuse flag
317
```