Para configurar múltiplas fontes de dados em uma aplicação Spring Boot com MyBatis, é necessário desativar a confiugração automática de datasource único. Isso é feito excluindo a classe DataSourceAutoConfiguration na anotação principal da aplicação.
Desativação da Configuração Automática
package com.exemplo.configuracao.multi;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
@SpringBootApplication(exclude = {
DataSourceAutoConfiguration.class
})
public class AplicacaoPrincipal {
public static void main(String[] args) {
SpringApplication.run(AplicacaoPrincipal.class, args);
}
}
Configuração das Propriedades
No arquivo application.properties, defina as conexões para cada banco de dados. Os preifxos podem ser personalizados conforme necessidade.
# Parâmetros comuns de conexão
conexao.parametros = useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&useLocalSessionState=true&tinyInt1isBit=false&serverTimezone=GMT%2B8
# Primeira fonte de dados
spring.datasource.principal.jdbc-url=jdbc:mysql://localhost:3306/banco_principal?${conexao.parametros}
spring.datasource.principal.username=usuario
spring.datasource.principal.password=senha123
spring.datasource.principal.driver-class-name=com.mysql.cj.jdbc.Driver
# Segunda fonte de dados
spring.datasource.segundaria.jdbc-url=jdbc:mysql://localhost:3306/banco_secundario?${conexao.parametros}
spring.datasource.segundaria.username=usuario
spring.datasource.segundaria.password=senha123
spring.datasource.segundaria.driver-class-name=com.mysql.cj.jdbc.Driver
package com.exemplo.configuracao.multi.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import javax.sql.DataSource;
@Configuration
public class ConfiguracaoDataSource {
@Primary
@Bean(name = "fontePrincipal")
@ConfigurationProperties(prefix = "spring.datasource.principal")
public DataSource dataSourcePrincipal() {
return DataSourceBuilder.create().build();
}
@Bean(name = "fonteSecundaria")
@ConfigurationProperties(prefix = "spring.datasource.segundaria")
public DataSource dataSourceSecundaria() {
return DataSourceBuilder.create().build();
}
}
Configuração do SqlSessionFactory para Cada Fonte
Configuração do Banco Principal
package com.exemplo.configuracao.multi.config;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import javax.sql.DataSource;
@Configuration
@MapperScan(
basePackages = "com.exemplo.configuracao.multi.repositorio.principal",
sqlSessionFactoryRef = "sessaoPrincipal"
)
public class ConfiguracaoBancoPrincipal {
private final DataSource fonteDados;
public ConfiguracaoBancoPrincipal(
@Qualifier("fontePrincipal") DataSource dataSource
) {
this.fonteDados = dataSource;
}
@Bean
public SqlSessionFactory sessaoPrincipal() throws Exception {
SqlSessionFactoryBean fabrica = new SqlSessionFactoryBean();
fabrica.setDataSource(fonteDados);
fabrica.setMapperLocations(
new PathMatchingResourcePatternResolver()
.getResources("classpath*:mapeamentos/principal/**/*.xml")
);
return fabrica.getObject();
}
@Bean
public SqlSessionTemplate modeloSessaoPrincipal() throws Exception {
return new SqlSessionTemplate(sessaoPrincipal());
}
}
Configuração do Banco Secundário
package com.exemplo.configuracao.multi.config;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import javax.sql.DataSource;
@Configuration
@MapperScan(
basePackages = "com.exemplo.configuracao.multi.repositorio.secundario",
sqlSessionFactoryRef = "sessaoSecundaria"
)
public class ConfiguracaoBancoSecundario {
private final DataSource fonteDados;
public ConfiguracaoBancoSecundario(
@Qualifier("fonteSecundaria") DataSource dataSource
) {
this.fonteDados = dataSource;
}
@Bean
public SqlSessionFactory sessaoSecundaria() throws Exception {
SqlSessionFactoryBean fabrica = new SqlSessionFactoryBean();
fabrica.setDataSource(fonteDados);
fabrica.setMapperLocations(
new PathMatchingResourcePatternResolver()
.getResources("classpath*:mapeamentos/secundario/**/*.xml")
);
return fabrica.getObject();
}
@Bean
public SqlSessionTemplate modeloSessaoSecundaria() throws Exception {
return new SqlSessionTemplate(sessaoSecundaria());
}
}
Após a configuração, a estrutura de pacotes deve seguir o padrão:
com.exemplo.configuracao.multi.repositorio.principal— Interfaces de mapeamento para o banco principalcom.exemplo.configuracao.multi.repositorio.secundario— Interfaces de mapeamento para o banco secundário
Os repositórios localizados em cada pacote serão automaticamente vinculados à respectiva fonte de dados através do MapperScan configurado.