DataSource
When using Spring Boot, configuration is very easy by default . Spring Boot will automatically configure one for us DataSource
.
If the relevant configuration application.yml
is specified in spring.datasource
, Spring Boot will create one with that configuration DataSource
. If there application.yml
is no spring.datasource
related configuration specified in , Spring Boot will search the classpath for jar packages of in-memory databases such as H2 and hsqldb. If found, an in-memory database will be automatically configured DataSource
, so we only need to introduce the jar package. For example, to configure an hsqldb data source:
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>runtime</scope>
</dependency>
However, in some cases, if we need to configure multiple data sources, how should we configure it in Spring Boot?
We take JDBC as an example to demonstrate how to configure both in Spring Boot DataSource
. Correspondingly, we will create two JdbcTemplate
beans to use these two data sources respectively.
First, we have application.yml
to declare the configuration for two data sources in, one using spring.datasource
and the other using spring.second-datasource
:
spring:
application:
name: data-multidatasource
datasource:
driver-class-name: org.hsqldb.jdbc.JDBCDriver
url: jdbc:hsqldb:mem:db1
username: sa
password:
second-datasource:
driver-class-name: org.hsqldb.jdbc.JDBCDriver
url: jdbc:hsqldb:mem:db2
username: sa
password:
Both DataSource
of these use hsqldb, but the databases are different. In addition, when using multiple data sources, all necessary configurations cannot be omitted.
Second, we need to create two DataSource
beans ourselves, one marked @Primary
and the other named secondDatasource
:
@Configuration
public class SomeConfiguration {
@Bean
@Primary
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "secondDatasource")
@ConfigurationProperties(prefix = "spring.second-datasource")
public DataSource secondDataSource() {
return DataSourceBuilder.create().build();
}
}
For each of them DataSource
, we have to @ConfigurationProperties(prefix = "xxx")
specify the prefix of the configuration item.
Next, we create two JdbcTemplate
beans, one of which is marked and the @Primary
other named secondJdbcTemplate
, using the corresponding DataSource
:
@Bean
@Primary
public JdbcTemplate primaryJdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
@Bean(name = "secondJdbcTemplate")
public JdbcTemplate secondJdbcTemplate(@Qualifier("secondDatasource") DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
Note that secondJdbcTemplate
when creating, the incoming DataSource
must be @Qualifier("secondDatasource")
declared, so that the second one can be used DataSource
.
Now , we have created two JdbcTemplate
. Bean
Where we need to use the first JdbcTemplate
, we inject directly:
@Component
public class SomeService {
@Autowired
JdbcTemplate jdbcTemplate;
}
Where we need to use the second one JdbcTemplate
, we need to use the flag when injecting @Qualifier("secondJdbcTemplate")
:
@Component
public class AnotherService {
@Autowired
@Qualifier("secondJdbcTemplate")
JdbcTemplate secondJdbcTemplate;
}
In this way, we can use different JdbcTemplate
operations for different data sources.
Precautions
When there are multiple beans of the same type, for example, multiple DataSource
, multiple JdbcTemplate
, it is strongly recommended to always use @Primary
one of the beans marked as "primary", and the bean @Autowired
marked as the first will be used when using injection @Primary
.
For other beans of the same type, each one needs to use an @Bean(name="xxx")
identifying name, and when using @Autowired
injection, @Qualifier("xxx")
specify the name of the injected bean.
For the complete sample project source code, please refer to:
https://github.com/michaelliao/springcloud/tree/master/data-multidatasource