2

Spring Boot 配置多数据源 - Grey Zeng

 1 year ago
source link: https://www.cnblogs.com/greyzeng/p/16938035.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Spring Boot 配置多数据源

作者:Grey

原文地址:

博客园:Spring Boot 配置多数据源

CSDN:Spring Boot 配置多数据源

说明#

本文主要介绍了 Spring Boot 下如何配置多数据源。

环境和版本#

Java 版本:17

Spring Boot 版本:3.0.0

数据库:H2

注:本示例基于 JdbcTemplate,如果使用 JPA,Hiberante 或者 Mybatis 等,方法类似。

代码说明#

首先,配置两个数据源,这里我们基于 H2 配置了两个简单数据源,由于 H2 是内存数据库,无需手动新建

foo.datasource.url=jdbc:h2:mem:foo
foo.datasource.username=sa
foo.datasource.password=
foo.datasource.driver-class-name=org.h2.Driver
bar.datasource.url=jdbc:h2:mem:bar
bar.datasource.username=sa
bar.datasource.password=
bar.datasource.driver-class-name=org.h2.Driver

接下来在 resources 新建一个 db 文件夹,里面存两个数据库的初始化脚本

schema.sql

DROP TABLE IF EXISTS USER_INFO;

CREATE TABLE USER_INFO
(
    id        INT AUTO_INCREMENT PRIMARY KEY,
    user_name VARCHAR(250) NOT NULL,
    email     VARCHAR(250) DEFAULT NULL
);

foo 数据源的初始化数据 foo-data.sql

INSERT INTO
    USER_INFO (user_name, email)
VALUES
    ('grey-foo', '[email protected]'),
    ('jack-foo', '[email protected]');

bar 数据源的初始化数据 bar-data.sql

INSERT INTO USER_INFO (user_name, email)
VALUES ('grey-bar', '[email protected]'),
       ('jack-bar', '[email protected]');

脚本和数据源配置好以后,接下来要准备两个数据源的配置类信息,以任意一个数据源的配置类信息为例(另外一个同理)

foo 数据源的配置信息如下

@Configuration
@ConfigurationProperties(prefix = "foo.datasource")
@Slf4j
public class FooDataSourceConfig {

  @Bean
  public PlatformTransactionManager fooTxManager(DataSource fooDataSource) {
    return new DataSourceTransactionManager(fooDataSource);
  }

  @Bean
  public DataSourceProperties fooDataSourceProperties() {
    return new DataSourceProperties();
  }

  @Bean
  @Primary
  public DataSource fooDataSource() {
    DataSourceProperties dataSourceProperties = fooDataSourceProperties();
    // schema init
    DatabasePopulator databasePopulator =
        new ResourceDatabasePopulator(
            new ClassPathResource("db/schema.sql"), new ClassPathResource("db/foo-data.sql"));
    DataSource ds = dataSourceProperties.initializeDataSourceBuilder().build();
    DatabasePopulatorUtils.execute(databasePopulator, ds);
    log.info("foo datasource: {}", dataSourceProperties.getUrl());
    return ds;
  }

  @Bean
  @Primary
  public JdbcTemplate fooJdbcTemplate(@Qualifier("fooDataSource") DataSource dataSource) {
    return new JdbcTemplate(dataSource);
  }
}

需要注意的点,@Primary参数定义了该数据源是主数据源,也就是说,调用数据源的时候,如果没有指定名称默认就是用这个数据源。

fooDataSource中,定义了初始化脚本的位置

 DatabasePopulator databasePopulator =
        new ResourceDatabasePopulator(
            new ClassPathResource("db/schema.sql"), new ClassPathResource("db/foo-data.sql"));

另外一个 BarDataSourceConfig 同理。

完成上述配置后,在启动类中注入这两个数据源对应的JdbcTemplate

@SpringBootApplication
@Slf4j
public class SpringMultiDatasourceApplication implements CommandLineRunner {
  private final JdbcTemplate fooTemplate;
  private final JdbcTemplate barTemplate;
  private final JdbcTemplate defaultTemplate;

  public SpringMultiDatasourceApplication(
      @Qualifier("fooJdbcTemplate") JdbcTemplate fooTemplate,
      @Qualifier("barJdbcTemplate") JdbcTemplate barTemplate,
      JdbcTemplate defaultTemplate) {
    this.fooTemplate = fooTemplate;
    this.barTemplate = barTemplate;
    this.defaultTemplate = defaultTemplate;
  }

  @Override
  public void run(String... args) throws Exception {
    fooTemplate.queryForList("SELECT * FROM USER_INFO").forEach(row -> log.info(row.toString()));
    log.info("----");
    barTemplate.queryForList("SELECT * FROM USER_INFO").forEach(row -> log.info(row.toString()));
    log.info("----");
    defaultTemplate
        .queryForList("SELECT * FROM USER_INFO")
        .forEach(row -> log.info(row.toString()));
  }
  
  public static void main(String[] args) {
    SpringApplication.run(SpringMultiDatasourceApplication.class, args);
  }

}

本示例中,注入了三个JdbcTemplate,其中两个通过@Qualifier指定了名称,还有一个defaultTemplate并未指定名称,所以取的就是有@Primary注解的JdbcTemplate

运行主函数,打印出如下信息

{ID=1, USER_NAME=grey-foo, [email protected]}
{ID=2, USER_NAME=jack-foo, [email protected]}
----
{ID=1, USER_NAME=grey-bar, [email protected]}
{ID=2, USER_NAME=jack-bar, [email protected]}
----
{ID=1, USER_NAME=grey-foo, [email protected]}
{ID=2, USER_NAME=jack-foo, [email protected]}

可以看到效果,默认的JdbcTemplate取的是 foo 数据源的信息。

完整代码#

spring-multi-datasource

参考资料#

Spring Boot 2 Multiple Datasources initialize schema

Configure and Use Multiple DataSources in Spring Boot


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK