두 개의 데이터 소스를 구성하고 사용하려면 어떻게해야합니까?
예를 들어 다음은 첫 번째 데이터 소스에 대한 것입니다.
application.properties
#first db
spring.datasource.url = [url]
spring.datasource.username = [username]
spring.datasource.password = [password]
spring.datasource.driverClassName = oracle.jdbc.OracleDriver
#second db ...
응용 수업
@SpringBootApplication
public class SampleApplication
{
public static void main(String[] args) {
SpringApplication.run(SampleApplication.class, args);
}
}
application.properties
다른 데이터 소스를 추가하려면 어떻게 수정 합니까? 다른 저장소에서 사용하기 위해 자동 와이어 링을 어떻게 수행합니까?
답변
여기 요
#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();
}
답변
Spring Boot 1.5.8로 업데이트 2018-01-07.RELEASE
대부분의 답변은 데이터 소스 자체 및 트랜잭션으로 사용하는 방법을 제공하지 않으며 구성하는 방법 만 제공합니다.
https://www.surasint.com/spring-boot-with-multiple-databases-example/ 에서 실행 가능한 예제와 일부 설명을 볼 수 있습니다.
여기에 코드를 복사했습니다.
먼저 다음과 같이 application.properties를 설정해야합니다.
#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
그런 다음 다음과 같이 공급자 (@Bean)로 정의하십시오.
@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();
}
@Bean (name = “datasource1”) 및 @Bean (name = “datasource2”)이 있으므로 @Qualifier ( “datasource1”) 및 @Qualifier ( “datasource2”)와 같은 데이터 소스가 필요할 때 사용할 수 있습니다. 예를 들어
@Qualifier("datasource1")
@Autowired
private DataSource dataSource;
트랜잭션에 관심이있는 경우 다음과 같이 두 가지에 대해 DataSourceTransactionManager를 정의해야합니다.
@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;
}
그런 다음처럼 사용할 수 있습니다
@Transactional //this will use the first datasource because it is @primary
또는
@Transactional("tm2")
이것으로 충분합니다. 위의 링크에서 예와 세부 사항을 참조하십시오.
답변
공식 문서를 참조하십시오
둘 이상의 데이터 소스를 작성하면 첫 번째 데이터 소스를 작성하는 것과 동일하게 작동합니다. JDBC 또는 JPA에 기본 자동 구성을 사용하는 경우 @Primary로 표시 할 수 있습니다 (그러면 @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();
}
답변
또한 Spring Boot 응용 프로그램에서 2 개의 데이터 소스에 대한 연결을 설정해야했지만 쉽지 않았습니다 .Spring Boot 설명서에 언급 된 솔루션이 작동하지 않았습니다. 인터넷을 통해 오랫동안 파고 들었을 때 나는 그것을 작동 시켰고 주요 아이디어는 이 기사 와 다른 곳 에서 가져 왔습니다 .
다음 해결책에 기록 된 코 틀린 와 함께 작동 봄 부팅 2.1.3 및 최대 절전 모드 코어 5.3.7 . 주요 문제는 다른 DataSource 구성 을 설정하는 것만으로는 충분하지 않았지만 두 데이터베이스 모두에 대해 EntityManagerFactory 및 TransactionManager 를 구성해야한다는 것 입니다.
첫 번째 (기본) 데이터베이스에 대한 구성은 다음과 같습니다.
@Configuration
@EnableJpaRepositories(
entityManagerFactoryRef = "firstDbEntityManagerFactory",
transactionManagerRef = "firstDbTransactionManager",
basePackages = ["org.path.to.firstDb.domain"]
)
@EnableTransactionManagement
class FirstDbConfig {
@Bean
@Primary
@ConfigurationProperties(prefix = "spring.datasource.firstDb")
fun firstDbDataSource(): DataSource {
return DataSourceBuilder.create().build()
}
@Primary
@Bean(name = ["firstDbEntityManagerFactory"])
fun firstDbEntityManagerFactory(
builder: EntityManagerFactoryBuilder,
@Qualifier("firstDbDataSource") dataSource: DataSource
): LocalContainerEntityManagerFactoryBean {
return builder
.dataSource(dataSource)
.packages(SomeEntity::class.java)
.persistenceUnit("firstDb")
// Following is the optional configuration for naming strategy
.properties(
singletonMap(
"hibernate.naming.physical-strategy",
"org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl"
)
)
.build()
}
@Primary
@Bean(name = ["firstDbTransactionManager"])
fun firstDbTransactionManager(
@Qualifier("firstDbEntityManagerFactory") firstDbEntityManagerFactory: EntityManagerFactory
): PlatformTransactionManager {
return JpaTransactionManager(firstDbEntityManagerFactory)
}
}
그리고 이것은 두 번째 데이터베이스의 구성입니다.
@Configuration
@EnableJpaRepositories(
entityManagerFactoryRef = "secondDbEntityManagerFactory",
transactionManagerRef = "secondDbTransactionManager",
basePackages = ["org.path.to.secondDb.domain"]
)
@EnableTransactionManagement
class SecondDbConfig {
@Bean
@ConfigurationProperties("spring.datasource.secondDb")
fun secondDbDataSource(): DataSource {
return DataSourceBuilder.create().build()
}
@Bean(name = ["secondDbEntityManagerFactory"])
fun secondDbEntityManagerFactory(
builder: EntityManagerFactoryBuilder,
@Qualifier("secondDbDataSource") dataSource: DataSource
): LocalContainerEntityManagerFactoryBean {
return builder
.dataSource(dataSource)
.packages(EntityFromSecondDb::class.java)
.persistenceUnit("secondDb")
.build()
}
@Bean(name = ["secondDbTransactionManager"])
fun secondDbTransactionManager(
@Qualifier("secondDbEntityManagerFactory") secondDbEntityManagerFactory: EntityManagerFactory
): PlatformTransactionManager {
return JpaTransactionManager(secondDbEntityManagerFactory)
}
}
데이터 소스의 속성은 다음과 같습니다.
spring.datasource.firstDb.jdbc-url=
spring.datasource.firstDb.username=
spring.datasource.firstDb.password=
spring.datasource.secondDb.jdbc-url=
spring.datasource.secondDb.username=
spring.datasource.secondDb.password=
특성을 가진 문제는 내가 정의했다이었다 JDBC-URL 대신 URL을 , 그렇지 않으면 나는 예외를 가지고 있기 때문이다.
ps
또한 데이터베이스에 다른 이름 지정 체계가있을 수 있습니다. Hibernate 5는 이전의 모든 명명 체계를 지원하지 않기 때문에이 답변의 솔루션을 사용해야 했습니다. 아마도 누군가를 도울 것입니다.
답변
완벽한 솔루션은 다음과 같습니다.
#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
두 개의 서로 다른 데이터베이스 (db1, db2)에 액세스하려면 다음과 같이 각 데이터 소스 구성을 개별적으로 구성해야합니다.
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<string, object=""> 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;
}
}
두 번째 데이터 소스 :
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<string, object=""> 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;
}
}
내 블로그에서 전체 예제를 찾을 수 있습니다 :
다중 데이터 소스 구성을 가진 Spring Boot
답변
# 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();
}
답변
mybatis-springboot 2.0 기술 스택, 솔루션을 사용했습니다.
//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;
}
}
2) —. “jdbc-url”속성-> Spring Boot 2.0 마이그레이션 후 : driverClassName에 jdbcUrl이 필요합니다.