You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

是否可创建指向多个MariaDB数据库的Testcontainer适配Quarkus多数据源测试

问题根因

你当前的代码写法存在逻辑错误:同一个MariaDBContainer实例多次调用withDatabaseName、withUsername、withPassword方法时,后配置的参数会直接覆盖之前的参数,最终容器启动后只会初始化1个名为SECOND_DB_NAME的数据库,因此测试时只能连接到一个数据源。

解决方案

方案一:启动两个独立的MariaDB容器实例(推荐,和生产多数据源场景匹配度更高)

  1. 声明两个独立的容器实例,分别对应两个数据源
// 第一个数据库容器
private static final MariaDBContainer FIRST_DATABASE = 
  new MariaDBContainer<>(DockerImageName.parse(DOCKER_IMAGE).asCompatibleSubstituteFor("mariadb"))
                    .withDatabaseName(FIRST_DB_NAME)
                    .withUsername(DB_USER)
                    .withPassword(DB_PASS);

// 第二个数据库容器
private static final MariaDBContainer SECOND_DATABASE = 
  new MariaDBContainer<>(DockerImageName.parse(DOCKER_IMAGE).asCompatibleSubstituteFor("mariadb"))
                    .withDatabaseName(SECOND_DB_NAME)
                    .withUsername(DB_USER)
                    .withPassword(DB_PASS);
  1. 启动容器并动态覆盖测试环境的数据源配置,配置前缀需和你application.properties中定义的多数据源名称完全匹配
static {
    // 启动两个容器
    FIRST_DATABASE.start();
    SECOND_DATABASE.start();
    // 覆盖第一个数据源配置,示例前缀为quarkus.datasource.first,需替换为你实际的数据源名
    System.setProperty("quarkus.datasource.first.jdbc.url", FIRST_DATABASE.getJdbcUrl());
    System.setProperty("quarkus.datasource.first.username", FIRST_DATABASE.getUsername());
    System.setProperty("quarkus.datasource.first.password", FIRST_DATABASE.getPassword());
    // 覆盖第二个数据源配置,示例前缀为quarkus.datasource.second,需替换为你实际的数据源名
    System.setProperty("quarkus.datasource.second.jdbc.url", SECOND_DATABASE.getJdbcUrl());
    System.setProperty("quarkus.datasource.second.username", SECOND_DATABASE.getUsername());
    System.setProperty("quarkus.datasource.second.password", SECOND_DATABASE.getPassword());
}

方案二:单容器内创建多数据库(资源占用更低)

如果不想启动两个容器,可通过初始化脚本在同一个MariaDB实例中创建两个数据库:

  1. 容器配置新增初始化脚本
private static final MariaDBContainer DATABASE = 
  new MariaDBContainer<>(DockerImageName.parse(DOCKER_IMAGE).asCompatibleSubstituteFor("mariadb"))
                    .withDatabaseName(FIRST_DB_NAME)
                    .withUsername(DB_USER)
                    .withPassword(DB_PASS)
                    // 配置初始化SQL脚本,放在test/resources目录下
                    .withInitScript("init_second_database.sql");
  1. 编写init_second_database.sql脚本,创建第二个数据库并授权
CREATE DATABASE IF NOT EXISTS <替换为你的SECOND_DB_NAME>;
GRANT ALL PRIVILEGES ON <替换为你的SECOND_DB_NAME>.* TO '<替换为你的DB_USER>'@'%';
FLUSH PRIVILEGES;
  1. 动态覆盖多数据源配置
static {
    DATABASE.start();
    // 第一个数据源配置
    System.setProperty("quarkus.datasource.first.jdbc.url", DATABASE.getJdbcUrl());
    System.setProperty("quarkus.datasource.first.username", DATABASE.getUsername());
    System.setProperty("quarkus.datasource.first.password", DATABASE.getPassword());
    // 第二个数据源配置,替换JDBC URL中的默认库名
    String secondJdbcUrl = DATABASE.getJdbcUrl().replace(FIRST_DB_NAME, SECOND_DB_NAME);
    System.setProperty("quarkus.datasource.second.jdbc.url", secondJdbcUrl);
    System.setProperty("quarkus.datasource.second.username", DATABASE.getUsername());
    System.setProperty("quarkus.datasource.second.password", DATABASE.getPassword());
}

注意事项

如果你的多数据源搭配了多Hibernate持久化单元使用,需保证测试中持久化单元和数据源的关联配置和application.properties中的生产配置完全一致即可。

内容的提问来源于stack exchange,提问作者John

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 21:48:04