简体   繁体   English

如何在Spring Boot Jdbc中为MySQL数据库指定特定的默认架构

[英]How to specific default schema for MySQL db in Spring Boot Jdbc

We are connecting to multiple databases from Spring boot. 我们正在从Spring Boot连接到多个数据库。

application.properties: application.properties:

datasource.target.url=jdbc:mysql://localhost:3306/db_test_1?useSSL=false
datasource.target.driver-class-name=com.mysql.jdbc.Driver

datasource.origin.url=jdbc:mysql://localhost:3306/db_test_2?useSSL=false
datasource.origin.driver-class-name=com.mysql.jdbc.Driver

Database Config: 数据库配置:

@Configuration
public class DatabaseConfig {

    @Bean(name = "originJdbcTemplate")
    public JdbcTemplate originJdbcTemplate() {
        return new JdbcTemplate(originDataSource());
    }

    @Bean(name = "targetJdbcTemplate")
    public JdbcTemplate targetJdbcTemplate() {
        return new JdbcTemplate(targetDataSource());
    }

    @Bean
    @Primary
    @ConfigurationProperties("datasource.origin")
    public DataSourceProperties originDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean
    @Primary
    @ConfigurationProperties("datasource.origin")
    public DataSource originDataSource() {
        return originDataSourceProperties().initializeDataSourceBuilder().build();
    }

    @Bean
    @ConfigurationProperties("datasource.target")
    public DataSourceProperties targetDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean
    @ConfigurationProperties("datasource.target")
    public DataSource targetDataSource() {
        return targetDataSourceProperties().initializeDataSourceBuilder().build();
    }

}

We are using Spring Jdbc template and we have to explicitly name the schema in each query even though we have defined the schema name in url above in application properties. 我们正在使用Spring Jdbc模板,即使我们已在应用程序属性中的url中定义了架构名称,我们也必须在每个查询中显式命名架构。 eg: The query without schema name doesn't work 例如:没有架构名称的查询不起作用

select * from db_test_1.user //works with schema name
select * from user //doesn't work

As per this SO Answer I should use Connection.setCatalog() , how do I do it in Spring configuration? 按照这个答案,我应该使用Connection.setCatalog() ,如何在Spring配置中使用它?

By using Delegating Datasource 通过使用委托数据源

class DefaultSchemaDelegatingDS extends DelegatingDataSource {
    private final String catalogName;

    public DefaultSchemaDelegatingDS(final String catalogName, final DataSource dataSource) {
        super(dataSource);
        this.catalogName = catalogName;
    }

    @Override
    public Connection getConnection() throws SQLException {
        final Connection connection = super.getConnection();
        connection.setCatalog(this.catalogName);
        return connection;
    }
}

and then in the DatabaseConfig 然后在DatabaseConfig中

@Configuration
public class DatabaseConfig {

    @Value("${datasource.target.default_schema}")
    private String defaultTargetSchema;

    @Value("${datasource.origin.default_schema}")
    private String defaultOriginSchema;

    @Bean(name = "originJdbcTemplate")
    public JdbcTemplate originJdbcTemplate() {
        return new JdbcTemplate(originDataSource());
    }

    @Bean(name = "targetJdbcTemplate")
    public JdbcTemplate targetJdbcTemplate() {
        return new JdbcTemplate(targetDataSource());
    }

    @Bean
    @Primary
    @ConfigurationProperties("datasource.origin")
    public DataSourceProperties originDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean
    @Primary
    @ConfigurationProperties("datasource.origin")
    public DataSource originDataSource() {
        final DataSource ds = originDataSourceProperties().initializeDataSourceBuilder().build();
        return new DefaultSchemaDelegatingDS(defaultOriginSchema, ds);
    }

    @Bean
    @ConfigurationProperties("datasource.target")
    public DataSourceProperties targetDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean
    @ConfigurationProperties("datasource.target")
    public DataSource targetDataSource() {
        final DataSource ds = targetDataSourceProperties().initializeDataSourceBuilder().build();
        return new DefaultSchemaDelegatingDS(defaultTargetSchema, ds);
    }
}

The other way without using the DelegatingDatasource was to simply add 不使用DelegatingDatasource的另一种方法是简单地添加

jdbcTemplate.getDataSource().getConnection().setCatalog(catalogName);

eg, 例如,

@Bean(name = "originJdbcTemplate")
public JdbcTemplate originJdbcTemplate() throws SQLException {
    JdbcTemplate jdbcTemplate = new JdbcTemplate(originDataSource());
    jdbcTemplate.getDataSource().getConnection().setCatalog(defaultOriginSchema);
    return jdbcTemplate;
}

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

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