Primeiro é necessário preencher as configurações dos DataSources no arquivo de configuração. No nosso caso utilizamos no formato YML (application.yml), para criar dois DataSources, um para o banco de dados chamado "usuarios" e outro para "mensagens":
spring:
datasource.mensagens:
username: root
url: jdbc:mysql://localhost:3306/awmensagens?createDatabaseIfNotExist=true&serverTimezone=UTC
password:
datasource.usuarios:
username: root
url: jdbc:mysql://localhost:3306/awusuarios?createDatabaseIfNotExist=true&serverTimezone=UTC
password:
Em seguida, é precisa ler essas configurações para de fato criar os DataSources:
@Configuration
public class DataSourceConfig {
@Bean
@ConfigurationProperties("spring.datasource.usuarios")
public DataSourceProperties usuariosDataSourceProperties() {
return new DataSourceProperties();
}
@Bean
@ConfigurationProperties("spring.datasource.mensagens")
public DataSourceProperties mensagensDataSourceProperties() {
return new DataSourceProperties();
}
@Bean
@Primary
public DataSource usuariosDataSource() {
return usuariosDataSourceProperties()
.initializeDataSourceBuilder()
.build();
}
@Bean
public DataSource mensagensDataSource() {
return mensagensDataSourceProperties()
.initializeDataSourceBuilder()
.build();
}
}
Importante ao menos um deles precisa ser @Primary, para que o Spring funcione corretamente. Em seguida, para cada um dos seus DataSources, é necessário configurar um EntityManager, assim poderemos gerenciar as Entities e Repositories em cada um dos bancos de dados.
Este seria o exemplo para DataSource "usuarios":
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
basePackages = "com.algaworks.example.usuario",
entityManagerFactoryRef = "usuariosEntityManagerFactory",
transactionManagerRef = "usuariosTransactionManager"
)
public class UsuarioJpaConfiguration {
@Bean
@Primary
public LocalContainerEntityManagerFactoryBean usuariosEntityManagerFactory(
@Qualifier("usuariosDataSource") DataSource usuariosDataSource,
EntityManagerFactoryBuilder builder) {
Map<String, Object> properties = new HashMap<String, Object>();
properties.put("hibernate.hbm2ddl.auto", "update");
return builder.dataSource(usuariosDataSource)
.packages("com.algaworks.example.usuario")
.properties(properties)
.build();
}
@Bean
public PlatformTransactionManager usuariosTransactionManager(
@Qualifier("usuariosEntityManagerFactory") LocalContainerEntityManagerFactoryBean usuariosEMF) {
return new JpaTransactionManager(Objects.requireNonNull(usuariosEMF.getObject()));
}
}
DataSource "mensagens":
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
basePackages = "com.algaworks.example.mensagem",
entityManagerFactoryRef = "mensagensEntityManagerFactory",
transactionManagerRef = "mensagensTransactionManager"
)
public class MensagemJpaConfiguration {
@Bean
public LocalContainerEntityManagerFactoryBean mensagensEntityManagerFactory(
@Qualifier("mensagensDataSource") DataSource mensagensDataSource,
EntityManagerFactoryBuilder builder) {
Map<String, Object> properties = new HashMap<String, Object>();
properties.put("hibernate.hbm2ddl.auto", "update");
return builder.dataSource(mensagensDataSource)
.properties(properties)
.packages("com.algaworks.example.mensagem")
.build();
}
@Bean
public PlatformTransactionManager mensagensTransactionManager(
@Qualifier("mensagensEntityManagerFactory") LocalContainerEntityManagerFactoryBean mensagensEMF) {
return new JpaTransactionManager(Objects.requireNonNull(mensagensEMF.getObject()));
}
}
Nota que também é necessário ao menos um EntityManager como @Primary. Essa configuração será válida apenas para o pacote e subpacotes de "com.algaworks.example.usuario", assim qualquer Entity ou Repository destes pacotes, utilizaram esse EntityManager.