在Spring Boot中,默认是使用单一数据源进行操作,如果要想配置多数据源的话,需要作出一些配置,主要包括以下部署,以使用 JdbcTemplate 为例。

配置数据库连接信息

分别配置两个数据test01test02,在application.yml 文件中的配置数据库信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
test01:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/test01?characterEncoding=utf8
username: root
password: "!qaz2wsx"

test02:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/test02?characterEncoding=utf8
username: root
password: "!qaz2wsx"

配置数据源信息

数据源的配置,主要包括三个部分:

  1. DataSourceProperties 数据库连接信息

    1
    2
    3
    4
    5
    @Bean
    @ConfigurationProperties("test01.datasource")
    public DataSourceProperties testOneDataSourceProperties() {
    return new DataSourceProperties();
    }
  2. DataSource 数据源

    1
    2
    3
    4
    5
    @Bean
    public DataSource testOneDataSource() {
    DataSourceProperties dataSourceProperties = testOneDataSourceProperties();
    return dataSourceProperties.initializeDataSourceBuilder().build();
    }
  3. PlatformTransactionManager 事物的管理

    1
    2
    3
    4
    5
    @Bean
    @Resource
    public PlatformTransactionManager testOneTxManager(DataSource testOneDataSource) {
    return new DataSourceTransactionManager(testOneDataSource);
    }
  1. 使用 JdbcTemplate , 还需要为其初始化

    1
    2
    3
    4
    @Bean
    public JdbcTemplate jdbcTemplateOne() {
    return new JdbcTemplate(testOneDataSource());
    }

以上操作完成了第一个数据源的配置,接下来配置第二个数据源,步骤和之前一样,只是在Bean name 不一样 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 /**
* Test Two
*
* Connection to Database test02
*/
@Bean
@ConfigurationProperties("test02.datasource")
public DataSourceProperties testTwoDataSourceProperties() {
return new DataSourceProperties();
}

@Bean
public DataSource testTwoDataSource() {
DataSourceProperties dataSourceProperties = testTwoDataSourceProperties();
return dataSourceProperties.initializeDataSourceBuilder().build();
}

@Bean
@Resource
public PlatformTransactionManager testTwoTxManager(DataSource testTwoDataSource) {
return new DataSourceTransactionManager(testTwoDataSource);
}

@Bean
public JdbcTemplate jdbcTemplateTwo() {
return new JdbcTemplate(testTwoDataSource());
}

移除Spring Boot 默认配置

Spring Boot 默认是会为我们加载一些配置,如果使用多数据源的情况,就需要移除一些默认加载项:

1
2
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class, JdbcTemplateAutoConfiguration.class })

准备脚本

分别在两个数据库中建立对应的表,以MYSQL为例:

test01:

1
2
3
4
5
CREATE TABLE `Person` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(45) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

test01

1
2
3
4
5
CREATE TABLE `Person` (
`id` int NOT NULL AUTO_INCREMENT,
`age` int DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

编写测试 Test

分别编写插入方法:MultipleDatasourceDemoApplicationTests.java `

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.proliu.multiple.datasource;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.JdbcTemplate;

@SpringBootTest
class MultipleDatasourceDemoApplicationTests {

@Autowired
private JdbcTemplate jdbcTemplateOne;

@Autowired
private JdbcTemplate jdbcTemplateTwo;

@Test
void testDatasourceOne() {
this.jdbcTemplateOne.update("insert into Person(name) values(?)", "test01");
}

@Test
void testDatasourceTwo() {
this.jdbcTemplateTwo.update("insert into Person(age) values(?)", 30);
}

}

测试事物

  1. 编写Service TestOneService.javaTestOneServiceImpl.java

    1
    2
    3
    4
    5
    6
    package com.proliu.multiple.datasource.service;

    public interface TestOneService {

    void savePerson();
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    package com.proliu.multiple.datasource.service;

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;

    @Transactional("testOneTxManager")
    @Service
    public class TestOneServiceImpl implements TestOneService {

    @Autowired
    private JdbcTemplate jdbcTemplateOne;


    @Override
    public void savePerson() {
    // TODO Auto-generated method stub
    this.jdbcTemplateOne.update("insert into Person(name) values(?)", "test20");
    this.jdbcTemplateOne.update("insert into Person(name) values(?)", "test21");
    throw new RuntimeException("This is test error");
    }

    }
  1. 编写单元测试 Unit test TestOneServiceTests.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    package com.proliu.multiple.datasource.service;

    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;

    @SpringBootTest
    public class TestOneServiceTests {

    @Autowired
    private TestOneService testOneService;

    @Test
    void testSavePerson() {
    this.testOneService.savePerson();;
    }
    }

    savePerson 方法会抛出异常, 启用默认事物管理,进行回滚操作。

代码

以上传代码到GitHub, 可以通过GitHub multiple-datasource-jdbc-demo 进行查看。