简体   繁体   English

使用具有不同 jdbc 驱动程序和 Spring 引导的两个数据源

[英]Using two datasources with different jdbc drivers with Spring Boot

I followed the documentation and created some sourcecode that is quite identical to the given example.我按照文档创建了一些与给定示例完全相同的源代码。 When I run my code I get this exception:当我运行我的代码时,我得到了这个异常:

java.lang.RuntimeException: Driver org.mariadb.jdbc.Driver claims to not accept jdbcUrl, jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE java.lang.RuntimeException: Driver org.mariadb.jdbc.Driver claims to not accept jdbcUrl, jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE

The strange thing is that two things are mixed:奇怪的是,有两件事混合在一起:

  • the h2-jdbcUrl is treated by the mariaDB-driver h2-jdbcUrl 由 mariaDB-driver 处理
  • the query that my previously existing code runs it targetted against mariaDB (I have not yet written any code that used the second datasource)我以前存在的代码运行的查询针对 mariaDB(我还没有编写任何使用第二个数据源的代码)

These are my beans:这些是我的豆子:

@Bean
@Primary
@ConfigurationProperties("datasources.first")
public DataSourceProperties firstDataSourceProperties() {
    return new DataSourceProperties();
}

@Bean
@Primary
@ConfigurationProperties("datasources.first.configuration")
public HikariDataSource firstDataSource() {
    return firstDataSourceProperties().initializeDataSourceBuilder().type(HikariDataSource.class).build();
}

@Bean
@ConfigurationProperties("datasources.second")
public DataSourceProperties secondDataSourceProperties() {
    return new DataSourceProperties();
}

@Bean
@ConfigurationProperties("datasources.second.configuration")
public HikariDataSource secondDataSource() {
    return secondDataSourceProperties().initializeDataSourceBuilder().type(HikariDataSource.class).build();
}

My application.yml looks like this:我的 application.yml 看起来像这样:

datasources:
  first:
    jdbcUrl: jdbc:mariadb://...
    username: ...
    password: ...
    driver-class-name: org.mariadb.jdbc.Driver
  second:
    jdbcUrl: jdbc:h2:/tmp/test;DB_CLOSE_ON_EXIT=FALSE
    username: ...
    password: ...
    driver-class-name: org.h2.Driver

This is the code that causes the exception:这是导致异常的代码:

@Component
public class Updater {

    @Autowired
    JdbcTemplate jdbcTemplate;

    @Autowired
    Queries queries;

    public List<User> getActiveUsers() throws Exception {
        List<User> users = jdbcTemplate.query(queries.getActive(), new UserRowMapper());

        return users;
    }

In order to diagnose this further I enabled the configprops and beans endpoints and checked their output.为了进一步诊断,我启用了configpropsbeans端点并检查了它们的 output。 The config looks good and the beans too:配置看起来不错,bean也是:

Config (one of many):配置(众多之一):

    "firstDataSourceProperties": {
      "prefix": "datasources.first",
      "properties": {
        "password": "******",
        "initializationMode": "EMBEDDED",
        "driverClassName": "org.mariadb.jdbc.Driver",
        "generateUniqueName": false,
        "xa": {
          "properties": {}
        },
        "separator": ";",
        "platform": "all",
        "continueOnError": false,
        "username": "..."
      }

Bean (one of many):豆(众多之一):

"firstDataSource": {
          "aliases": [],
          "scope": "singleton",
          "type": "com.zaxxer.hikari.HikariDataSource",
          "resource": "...Application",
          "dependencies": [
            "firstDataSourceProperties"
          ]
        }

I use Spring Boot 2.2.6我使用 Spring 启动 2.2.6

This problem was caused by me not understanding the interaction between DataSourceProperties and HikariDataSource .这个问题是由于我不了解DataSourcePropertiesHikariDataSource之间的交互引起的。

I found out that the jdbcUrl didn't carry the value I configured, this could be seen by the details of the firstDataSource :我发现jdbcUrl没有携带我配置的值,这可以从firstDataSource的详细信息中看出:

"firstDataSource": {
  "prefix": "datasources.first.configuration",
  "properties": {
    "initializationFailTimeout": 1,
    "validationTimeout": 5000,
    "readOnly": false,
    "registerMbeans": false,
    "healthCheckProperties": {},
    "isolateInternalQueries": false,
    "leakDetectionThreshold": 0,
    "maxLifetime": 1800000,
    "minimumIdle": 10,
    "metricsTrackerFactory": {},
    "allowPoolSuspension": false,
    "idleTimeout": 600000,
    "dataSourceProperties": {},
    "driverClassName": "org.mariadb.jdbc.Driver",
    "jdbcUrl": "jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE",
    "loginTimeout": 0,
    "maximumPoolSize": 10,
    "autoCommit": true,
    "connectionTimeout": 30000,
    "username": "...",
    "poolName": "HikariPool-1"
}

As you can see the jdbcUrl addresses h2.如您所见, jdbcUrl地址为 h2。 This is caused by the fact that I set "my" intended url at datasources.first.jdbcUrl .这是因为我在datasources.first.jdbcUrl设置了“我的”预期 url 。 But after that the (non-existing) value of datasources.first.configuration.jdbcUrl was read which was not configured and obviously set to a default.但之后读取了datasources.first.configuration.jdbcUrl的(不存在的)值,该值未配置并且显然设置为默认值。

After I changed my application.yml to this it worked:在我将 application.yml 更改为此之后,它起作用了:

datasources:
  first:
    username: ...
    password: ...
    driver-class-name: org.mariadb.jdbc.Driver
    configuration:
      jdbcUrl: jdbc:mariadb://...

I will need to decide which value to put where, the username and password could be moved one level deeper too, but that's another story...我需要决定将哪个值放在哪里, usernamepassword也可以更深一层,但那是另一回事了......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM