Inicialização do Spring Configure e use dois DataSources

Eu sou novo no Spring e Spring Boot. Como alguém poderia configurar e usar duas fonts de dados?

Por exemplo, aqui está o que eu tenho para a primeira fonte de dados.

application.properties

#first db spring.datasource.url = [url] spring.datasource.username = [username] spring.datasource.password = [password] spring.datasource.driverClassName = oracle.jdbc.OracleDriver #second db ... 

Classe de aplicação

 @SpringBootApplication public class SampleApplication { private static final Logger logger = LoggerFactory.getLogger(SampleApplication.class); public static void main(String[] args) { SpringApplication.run(SampleApplication.class, args); } @Autowired SampleRepository repo; @PostConstruct public void testDriving(){ logger.debug(repo.findSomeSample("id", "other")); } } 

Como modifico application.properties para adicionar outra fonte de dados? Como faço para que seja usado por um repository diferente?

   

Aqui está

 #first db spring.datasource.url = [url] spring.datasource.username = [username] spring.datasource.password = [password] spring.datasource.driverClassName = oracle.jdbc.OracleDriver #second db ... spring.secondDatasource.url = [url] spring.secondDatasource.username = [username] spring.secondDatasource.password = [password] spring.secondDatasource.driverClassName = oracle.jdbc.OracleDriver @Bean @Primary @ConfigurationProperties(prefix="spring.datasource") public DataSource primaryDataSource() { return DataSourceBuilder.create().build(); } @Bean @ConfigurationProperties(prefix="spring.secondDatasource") public DataSource secondaryDataSource() { return DataSourceBuilder.create().build(); } 

Consulte a documentação oficial


Criar mais de uma fonte de dados funciona da mesma forma que criar a primeira. Você pode querer marcar um deles como @Primary se você estiver usando a configuração automática padrão para JDBC ou JPA (então esse será escolhido por qualquer injeção @Autowired).

 @Bean @Primary @ConfigurationProperties(prefix="datasource.primary") public DataSource primaryDataSource() { return DataSourceBuilder.create().build(); } @Bean @ConfigurationProperties(prefix="datasource.secondary") public DataSource secondaryDataSource() { return DataSourceBuilder.create().build(); } 

Atualização 2018-01-07 com Spring Boot 1.5.8.RELEASE

A maioria das respostas não fornece como usá-las (como fonte de dados e como transação), apenas como configurá-las.

Você pode ver o exemplo executável e algumas explicações em https://www.surasint.com/spring-boot-with-multiple-databases-example/

Eu copiei algum código aqui.

Primeiro você tem que definir application.properties como este

 #Database database1.datasource.url=jdbc:mysql://localhost/testdb database1.datasource.username=root database1.datasource.password=root database1.datasource.driver-class-name=com.mysql.jdbc.Driver database2.datasource.url=jdbc:mysql://localhost/testdb2 database2.datasource.username=root database2.datasource.password=root database2.datasource.driver-class-name=com.mysql.jdbc.Driver 

Em seguida, defina-os como provedores (@Bean) assim:

 @Bean(name = "datasource1") @ConfigurationProperties("database1.datasource") @Primary public DataSource dataSource(){ return DataSourceBuilder.create().build(); } @Bean(name = "datasource2") @ConfigurationProperties("database2.datasource") public DataSource dataSource2(){ return DataSourceBuilder.create().build(); } 

Note que eu tenho @Bean (name = “datasource1”) e @Bean (name = “datasource2”), então você pode usá-lo quando precisarmos de datasource como @Qualifier (“datasource1”) e @Qualifier (“datasource2”), por exemplo

 @Qualifier("datasource1") @Autowired private DataSource dataSource; 

Se você se importa com transação, você tem que definir DataSourceTransactionManager para ambos, assim:

 @Bean(name="tm1") @Autowired @Primary DataSourceTransactionManager tm1(@Qualifier ("datasource1") DataSource datasource) { DataSourceTransactionManager txm = new DataSourceTransactionManager(datasource); return txm; } @Bean(name="tm2") @Autowired DataSourceTransactionManager tm2(@Qualifier ("datasource2") DataSource datasource) { DataSourceTransactionManager txm = new DataSourceTransactionManager(datasource); return txm; } 

Então você pode usá-lo como

 @Transactional //this will use the first datasource because it is @primary 

ou

 @Transactional("tm2") 

Isso deve ser o suficiente. Veja o exemplo e detalhe no link acima.

Aqui está a solução completa

 #First Datasource (DB1) db1.datasource.url: url db1.datasource.username:user db1.datasource.password:password #Second Datasource (DB2) db2.datasource.url:url db2.datasource.username:user db2.datasource.password:password 

Como vamos obter access a dois bancos de dados diferentes (db1, db2), precisamos configurar cada configuração de fonte de dados separadamente, como:

 public class DB1_DataSource { @Autowired private Environment env; @Bean @Primary public LocalContainerEntityManagerFactoryBean db1EntityManager() { LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); em.setDataSource(db1Datasource()); em.setPersistenceUnitName("db1EntityManager"); HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); em.setJpaVendorAdapter(vendorAdapter); HashMap properties = new HashMap<>(); properties.put("hibernate.dialect", env.getProperty("hibernate.dialect")); properties.put("hibernate.show-sql", env.getProperty("jdbc.show-sql")); em.setJpaPropertyMap(properties); return em; } @Primary @Bean public DataSource db1Datasource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName( env.getProperty("jdbc.driver-class-name")); dataSource.setUrl(env.getProperty("db1.datasource.url")); dataSource.setUsername(env.getProperty("db1.datasource.username")); dataSource.setPassword(env.getProperty("db1.datasource.password")); return dataSource; } @Primary @Bean public PlatformTransactionManager db1TransactionManager() { JpaTransactionManager transactionManager = new JpaTransactionManager(); transactionManager.setEntityManagerFactory( db1EntityManager().getObject()); return transactionManager; } } 

Segunda fonte de dados:

 public class DB2_DataSource { @Autowired private Environment env; @Bean public LocalContainerEntityManagerFactoryBean db2EntityManager() { LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); em.setDataSource(db2Datasource()); em.setPersistenceUnitName("db2EntityManager"); HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); em.setJpaVendorAdapter(vendorAdapter); HashMap properties = new HashMap<>(); properties.put("hibernate.dialect", env.getProperty("hibernate.dialect")); properties.put("hibernate.show-sql", env.getProperty("jdbc.show-sql")); em.setJpaPropertyMap(properties); return em; } @Bean public DataSource db2Datasource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName( env.getProperty("jdbc.driver-class-name")); dataSource.setUrl(env.getProperty("db2.datasource.url")); dataSource.setUsername(env.getProperty("db2.datasource.username")); dataSource.setPassword(env.getProperty("db2.datasource.password")); return dataSource; } @Bean public PlatformTransactionManager db2TransactionManager() { JpaTransactionManager transactionManager = new JpaTransactionManager(); transactionManager.setEntityManagerFactory( db2EntityManager().getObject()); return transactionManager; } } 

Aqui você pode encontrar o exemplo completo no meu blog: Spring Boot with Multiple DataSource Configuration

Eu usei mybatis – springboot 2.0 tech stack, solution:

 //application.properties - start sp.ds1.jdbc-url=jdbc:mysql://localhost:3306/mydb?useSSL=false sp.ds1.username=user sp.ds1.password=pwd sp.ds1.testWhileIdle=true sp.ds1.validationQuery=SELECT 1 sp.ds1.driverClassName=com.mysql.jdbc.Driver sp.ds2.jdbc-url=jdbc:mysql://localhost:4586/mydb?useSSL=false sp.ds2.username=user sp.ds2.password=pwd sp.ds2.testWhileIdle=true sp.ds2.validationQuery=SELECT 1 sp.ds2.driverClassName=com.mysql.jdbc.Driver //application.properties - end //configuration class @Configuration @ComponentScan(basePackages = "com.mypkg") public class MultipleDBConfig { public static final String SQL_SESSION_FACTORY_NAME_1 = "sqlSessionFactory1"; public static final String SQL_SESSION_FACTORY_NAME_2 = "sqlSessionFactory2"; public static final String MAPPERS_PACKAGE_NAME_1 = "com.mypg.mymapper1"; public static final String MAPPERS_PACKAGE_NAME_2 = "com.mypg.mymapper2"; @Bean(name = "mysqlDb1") @Primary @ConfigurationProperties(prefix = "sp.ds1") public DataSource dataSource1() { System.out.println("db1 datasource"); return DataSourceBuilder.create().build(); } @Bean(name = "mysqlDb2") @ConfigurationProperties(prefix = "sp.ds2") public DataSource dataSource2() { System.out.println("db2 datasource"); return DataSourceBuilder.create().build(); } @Bean(name = SQL_SESSION_FACTORY_NAME_1) @Primary public SqlSessionFactory sqlSessionFactory1(@Qualifier("mysqlDb1") DataSource dataSource1) throws Exception { System.out.println("sqlSessionFactory1"); SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); sqlSessionFactoryBean.setTypeHandlersPackage(MAPPERS_PACKAGE_NAME_1); sqlSessionFactoryBean.setDataSource(dataSource1); SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBean.getObject(); sqlSessionFactory.getConfiguration().setMapUnderscoreToCamelCase(true); sqlSessionFactory.getConfiguration().setJdbcTypeForNull(JdbcType.NULL); return sqlSessionFactory; } @Bean(name = SQL_SESSION_FACTORY_NAME_2) public SqlSessionFactory sqlSessionFactory2(@Qualifier("mysqlDb2") DataSource dataSource2) throws Exception { System.out.println("sqlSessionFactory2"); SqlSessionFactoryBean diSqlSessionFactoryBean = new SqlSessionFactoryBean(); diSqlSessionFactoryBean.setTypeHandlersPackage(MAPPERS_PACKAGE_NAME_2); diSqlSessionFactoryBean.setDataSource(dataSource2); SqlSessionFactory sqlSessionFactory = diSqlSessionFactoryBean.getObject(); sqlSessionFactory.getConfiguration().setMapUnderscoreToCamelCase(true); sqlSessionFactory.getConfiguration().setJdbcTypeForNull(JdbcType.NULL); return sqlSessionFactory; } @Bean @Primary public MapperScannerConfigurer mapperScannerConfigurer1() { System.out.println("mapperScannerConfigurer1"); MapperScannerConfigurer configurer = new MapperScannerConfigurer(); configurer.setBasePackage(MAPPERS_PACKAGE_NAME_1); configurer.setSqlSessionFactoryBeanName(SQL_SESSION_FACTORY_NAME_1); return configurer; } @Bean public MapperScannerConfigurer mapperScannerConfigurer2() { System.out.println("mapperScannerConfigurer2"); MapperScannerConfigurer configurer = new MapperScannerConfigurer(); configurer.setBasePackage(MAPPERS_PACKAGE_NAME_2); configurer.setSqlSessionFactoryBeanName(SQL_SESSION_FACTORY_NAME_2); return configurer; } } 

Nota: 1) @ Primário -> @primary

2) —. “Jdbc-url” em propriedades -> Após a migration do Spring Boot 2.0: jdbcUrl é necessário com o driverClassName

 # Here '1stDB' is the database name spring.datasource.url=jdbc:mysql://localhost/A spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=com.mysql.jdbc.Driver # Here '2ndDB' is the database name spring.second-datasourcee.url=jdbc:mysql://localhost/B spring.second-datasource.username=root spring.second-datasource.password=root spring.second-datasource.driver-class-name=com.mysql.jdbc.Driver @Bean @Primary @ConfigurationProperties(prefix = "spring.datasource") public DataSource firstDataSource() { return DataSourceBuilder.create().build(); } @Bean @ConfigurationProperties(prefix = "spring.second-datasource") public DataSource secondDataSource() { return DataSourceBuilder.create().build(); }