Spring 配置多数据源

1. 项目结构

image.png

2. 启动文件

禁止数据源自动配置

1
2
3
4
5
6
7
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@ServletComponentScan("com.chemyun.mall.api.filter")
public class OpenApiApplication {
public static void main(String[] args) {
SpringApplication.run(OpenApiApplication.class, args);
}
}

3. Properties 文件

application.yml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
spring:
datasource:
master:
url: jdbc:mysql://172.19.253.52:9527/chemme?autoCommit=true&useUnicode=true&autoReconnect=true&allowMultiQueries=true
username: chemme
password: hEJpiLR162xRCBqYcNEwck4Ulr3A66OtfGUalzDAOMwvtB3RaPsfD0nylr7mOry8kOyd2BQiYIgNyzXF8q1T3A==
driver-class-name: com.mysql.jdbc.Driver
filters: stat,slf4j,config
initial-size: 1
min-idle: 1
max-active: 10
max-wait: 60000
use-global-data-source-stat: true
connectProperties:
druid.stat.slowSqlMillis: 5000
config.decrypt: true
config.decrypt.key: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJ3JZ3D6h+2OasZg1OMptc1KPKabNAp1IaqL9CeoLrsrDlQAdTpJZrRvKxISiWuwPb96KaW+vkOxfhWrWm9txukCAwEAAQ==
slave:
url: jdbc:sqlserver://124.160.116.211:1434;DatabaseName=chemcndata
username: chemme
password: chemme@20181121
driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver

AbstractDataBaseProperties:

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
@Setter
@Getter
public abstract class AbstractDataBaseProperties {
private String url;

private String username;

private String password;

private String driverClassName;

private String filters = "";

private int initialSize = 0;

private int minIdle = 0;

private int maxActive = 8;

private int maxWait = -1;

private boolean useGlobalDataSourceStat = false;

private Map<String, String> connectProperties;
}

MasterDataBaseProperties:

1
2
3
@ConfigurationProperties(prefix = "spring.datasource.master")
public class MasterDataBaseProperties extends AbstractDataBaseProperties {
}

SlaveDataBaseProperties:

1
2
3
@ConfigurationProperties(prefix = "spring.datasource.slave")
public class SlaveDataBaseProperties extends AbstractDataBaseProperties {
}

4. 数据源配置

MasterDataSourceConfig:

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
@Configuration
@EnableConfigurationProperties(MasterDataBaseProperties.class)
@MapperScan(basePackages = MasterDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "masterSqlSessionFactory")
public class MasterDataSourceConfig {
static final String PACKAGE = "com.chemyun.mall.api.dal.mapper";
static final String MAPPER_LOCATION = "classpath:com/chemyun/mall/api/dal/mapper/*.xml";

@Autowired
private MasterDataBaseProperties masterDataBaseProperties;

@Primary
@Bean(name = "masterDataSource")
public DataSource masterDataSource() throws SQLException {
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setDriverClassName(masterDataBaseProperties.getDriverClassName());
druidDataSource.setUrl(masterDataBaseProperties.getUrl());
druidDataSource.setUsername(masterDataBaseProperties.getUsername());
druidDataSource.setPassword(masterDataBaseProperties.getPassword());

druidDataSource.setFilters(masterDataBaseProperties.getFilters());

druidDataSource.setInitialSize(masterDataBaseProperties.getInitialSize());
druidDataSource.setMinIdle(masterDataBaseProperties.getMinIdle());
druidDataSource.setMaxActive(masterDataBaseProperties.getMaxActive());
druidDataSource.setMaxWait(masterDataBaseProperties.getMaxWait());
druidDataSource.setUseGlobalDataSourceStat(masterDataBaseProperties.isUseGlobalDataSourceStat());

// connectProperties
Map<String, String> connectProperties = masterDataBaseProperties.getConnectProperties();
if (!CollectionUtils.isEmpty(connectProperties)) {
Properties properties = new Properties();

for (Map.Entry<String, String> connectPropertie : connectProperties.entrySet()) {
properties.setProperty(connectPropertie.getKey(), connectPropertie.getValue());
}
druidDataSource.setConnectProperties(properties);
}

return druidDataSource;
}

@Primary
@Bean(name = "masterTransactionManager")
public DataSourceTransactionManager masterTransactionManager() throws SQLException {
return new DataSourceTransactionManager(masterDataSource());
}

@Primary
@Bean(name = "masterSqlSessionFactory")
public SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource") DataSource masterDataSource)
throws Exception {
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(masterDataSource);
sessionFactory.setMapperLocations(
new PathMatchingResourcePatternResolver().getResources(MasterDataSourceConfig.MAPPER_LOCATION));
return sessionFactory.getObject();
}
}

SlaveDataSourceConfig:

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
28
29
30
31
32
33
34
35
@Configuration
@EnableConfigurationProperties(SlaveDataBaseProperties.class)
@MapperScan(basePackages = SlaveDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "slaveSqlSessionFactory")
public class SlaveDataSourceConfig {
static final String PACKAGE = "com.chemyun.mall.api.dal.slave";
static final String MAPPER_LOCATION = "classpath:com/chemyun/mall/api/dal/slave/*.xml";

@Autowired
private SlaveDataBaseProperties slaveDataBaseProperties;

@Bean(name = "slaveDataSource")
public DataSource slaveDataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(slaveDataBaseProperties.getDriverClassName());
dataSource.setUrl(slaveDataBaseProperties.getUrl());
dataSource.setUsername(slaveDataBaseProperties.getUsername());
dataSource.setPassword(slaveDataBaseProperties.getPassword());
return dataSource;
}

@Bean(name = "slaveTransactionManager")
public DataSourceTransactionManager slaveTransactionManager() {
return new DataSourceTransactionManager(slaveDataSource());
}

@Bean(name = "slaveSqlSessionFactory")
public SqlSessionFactory slaveSqlSessionFactory(@Qualifier("slaveDataSource") DataSource slaveDataSource)
throws Exception {
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(slaveDataSource);
sessionFactory.setMapperLocations(
new PathMatchingResourcePatternResolver().getResources(SlaveDataSourceConfig.MAPPER_LOCATION));
return sessionFactory.getObject();
}
}