Testcontainers implementation for MariaDB - provides lightweight, throwaway instances of MariaDB databases for Java testing
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.
Wraps a MariaDB container to provide R2DBC connectivity and connection factory configuration.
/**
* R2DBC wrapper for MariaDB containers supporting reactive database access
* Delegates Startable methods to the underlying MariaDB container
*/
@RequiredArgsConstructor
public class MariaDBR2DBCDatabaseContainer implements R2DBCDatabaseContainer {
/**
* Creates connection factory options from a MariaDB container
* @param container MariaDB container instance
* @return Configured ConnectionFactoryOptions for R2DBC
*/
public static ConnectionFactoryOptions getOptions(MariaDBContainer<?> container);
/**
* Configures connection options with container connection details
* @param options Base connection factory options
* @return Options configured with host, port, database, and credentials
*/
public ConnectionFactoryOptions configure(ConnectionFactoryOptions options);
}Usage Examples:
import org.testcontainers.containers.MariaDBContainer;
import org.testcontainers.containers.MariaDBR2DBCDatabaseContainer;
import io.r2dbc.spi.ConnectionFactory;
import io.r2dbc.spi.ConnectionFactories;
import io.r2dbc.spi.ConnectionFactoryOptions;
// Create MariaDB container and R2DBC wrapper
MariaDBContainer<?> mariadbContainer = new MariaDBContainer<>("mariadb:10.3.39")
.withDatabaseName("reactive_db")
.withUsername("r2dbc_user")
.withPassword("r2dbc_pass");
MariaDBR2DBCDatabaseContainer r2dbcContainer = new MariaDBR2DBCDatabaseContainer(mariadbContainer);
// Start the container
r2dbcContainer.start();
// Get R2DBC connection factory options
ConnectionFactoryOptions options = MariaDBR2DBCDatabaseContainer.getOptions(mariadbContainer);
// Create connection factory
ConnectionFactory connectionFactory = ConnectionFactories.get(options);
// Use with reactive code
Mono<Void> result = Mono.from(connectionFactory.create())
.flatMap(connection ->
Mono.from(connection.createStatement("SELECT 1").execute())
.flatMap(result -> Mono.from(result.map((row, metadata) -> row.get(0))))
.doFinally(signalType -> connection.close())
);Factory for creating R2DBC MariaDB containers from connection factory options, enabling declarative container management.
/**
* Provider for creating R2DBC MariaDB containers from connection factory options
*/
public class MariaDBR2DBCDatabaseContainerProvider implements R2DBCDatabaseContainerProvider {
/**
* The R2DBC driver identifier for MariaDB (package-private constant)
* Value: "mariadb"
*/
// Note: DRIVER constant is package-private, not part of public API
/**
* Checks if this provider supports the connection options
* @param options Connection factory options to check
* @return true if driver is "mariadb"
*/
public boolean supports(ConnectionFactoryOptions options);
/**
* Creates R2DBC container from connection options
* @param options Connection factory options specifying database and configuration
* @return MariaDBR2DBCDatabaseContainer configured from options
*/
public R2DBCDatabaseContainer createContainer(ConnectionFactoryOptions options);
/**
* Returns connection metadata with default user/password if not specified
* @param options Connection factory options
* @return Connection metadata with defaults applied
*/
@Nullable
public ConnectionFactoryMetadata getMetadata(ConnectionFactoryOptions options);
}Usage Examples:
import io.r2dbc.spi.ConnectionFactoryOptions;
import org.testcontainers.containers.MariaDBR2DBCDatabaseContainerProvider;
import org.testcontainers.r2dbc.R2DBCDatabaseContainer;
// Create container from connection options
ConnectionFactoryOptions options = ConnectionFactoryOptions.builder()
.option(ConnectionFactoryOptions.DRIVER, "mariadb")
.option(ConnectionFactoryOptions.DATABASE, "test_reactive")
.option(IMAGE_TAG_OPTION, "10.3.39")
.option(REUSABLE_OPTION, true)
.build();
MariaDBR2DBCDatabaseContainerProvider provider = new MariaDBR2DBCDatabaseContainerProvider();
if (provider.supports(options)) {
R2DBCDatabaseContainer container = provider.createContainer(options);
container.start();
// Get configured connection options
ConnectionFactoryOptions configuredOptions = container.configure(options);
}Automatic container creation from R2DBC URL patterns for seamless integration with R2DBC libraries.
// R2DBC URL patterns supported:
// r2dbc:tc:mariadb:///databasename?TC_IMAGE_TAG=version
// r2dbc:tc:mariadb:///databasename?TC_IMAGE_TAG=version&REUSABLE=trueUsage Examples:
import io.r2dbc.spi.ConnectionFactories;
import io.r2dbc.spi.ConnectionFactory;
// Automatic container creation from R2DBC URL
String r2dbcUrl = "r2dbc:tc:mariadb:///testdb?TC_IMAGE_TAG=10.3.39";
ConnectionFactory connectionFactory = ConnectionFactories.get(r2dbcUrl);
// Container is automatically created, started, and managed
Flux<Integer> results = Flux.usingWhen(
connectionFactory.create(),
connection -> Flux.from(connection.createStatement("SELECT 1").execute())
.flatMap(result -> result.map((row, metadata) -> row.get(0, Integer.class))),
Connection::close
);
// Use in reactive streams
results.subscribe(value -> System.out.println("Result: " + value));Configures R2DBC connection factory options with container connection details.
/**
* Connection factory options configuration
* Maps container connection details to R2DBC connection options
*/
public ConnectionFactoryOptions configure(ConnectionFactoryOptions options) {
return options.mutate()
.option(ConnectionFactoryOptions.HOST, container.getHost())
.option(ConnectionFactoryOptions.PORT, container.getMappedPort(MariaDBContainer.MARIADB_PORT))
.option(ConnectionFactoryOptions.DATABASE, container.getDatabaseName())
.option(ConnectionFactoryOptions.USER, container.getUsername())
.option(ConnectionFactoryOptions.PASSWORD, container.getPassword())
.build();
}Usage Examples:
// Manual configuration of connection factory options
MariaDBContainer<?> container = new MariaDBContainer<>("mariadb:10.3.39")
.withDatabaseName("r2dbc_test")
.withUsername("reactive_user")
.withPassword("reactive_pass");
container.start();
// Base options
ConnectionFactoryOptions baseOptions = ConnectionFactoryOptions.builder()
.option(ConnectionFactoryOptions.DRIVER, "mariadb")
.build();
// Configure with container details
MariaDBR2DBCDatabaseContainer r2dbcContainer = new MariaDBR2DBCDatabaseContainer(container);
ConnectionFactoryOptions configuredOptions = r2dbcContainer.configure(baseOptions);
// Create connection factory
ConnectionFactory factory = ConnectionFactories.get(configuredOptions);@TestConfiguration
public class R2DBCTestConfiguration {
@Container
static MariaDBContainer<?> mariadb = new MariaDBContainer<>("mariadb:10.3.39");
@Bean
@Primary
public ConnectionFactory connectionFactory() {
return ConnectionFactories.get(MariaDBR2DBCDatabaseContainer.getOptions(mariadb));
}
@Bean
public R2dbcEntityTemplate r2dbcEntityTemplate(ConnectionFactory connectionFactory) {
return new R2dbcEntityTemplate(connectionFactory);
}
}@Testcontainers
class ReactiveMariaDBTest {
@Container
static MariaDBContainer<?> mariadb = new MariaDBContainer<>("mariadb:10.3.39")
.withDatabaseName("reactive_test");
private ConnectionFactory connectionFactory;
@BeforeEach
void setUp() {
connectionFactory = ConnectionFactories.get(
MariaDBR2DBCDatabaseContainer.getOptions(mariadb)
);
}
@Test
void testReactiveQuery() {
StepVerifier.create(
Mono.from(connectionFactory.create())
.flatMap(connection ->
Mono.from(connection.createStatement("SELECT 42").execute())
.flatMap(result -> Mono.from(result.map((row, metadata) ->
row.get(0, Integer.class))))
.doFinally(signalType -> connection.close())
)
)
.expectNext(42)
.verifyComplete();
}
}For R2DBC support, include these dependencies:
<!-- Maven -->
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>r2dbc</artifactId>
<version>1.21.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mariadb</groupId>
<artifactId>r2dbc-mariadb</artifactId>
<version>1.0.3</version>
<scope>test</scope>
</dependency>// Gradle
testImplementation 'org.testcontainers:r2dbc:1.21.3'
testRuntimeOnly 'org.mariadb:r2dbc-mariadb:1.0.3'import io.r2dbc.spi.ConnectionFactoryOptions;
import io.r2dbc.spi.ConnectionFactoryMetadata;
import org.testcontainers.r2dbc.R2DBCDatabaseContainer;
import org.testcontainers.r2dbc.R2DBCDatabaseContainerProvider;
import org.testcontainers.lifecycle.Startable;
// Standard R2DBC connection options
ConnectionFactoryOptions.DRIVER // "mariadb"
ConnectionFactoryOptions.HOST // Container host
ConnectionFactoryOptions.PORT // Mapped port (3306)
ConnectionFactoryOptions.DATABASE // Database name
ConnectionFactoryOptions.USER // Username
ConnectionFactoryOptions.PASSWORD // Password
// Testcontainers-specific options
IMAGE_TAG_OPTION // Docker image tag
REUSABLE_OPTION // Container reuse flagInstall with Tessl CLI
npx tessl i tessl/maven-org-testcontainers--mariadb