티스토리 뷰
하나의 application에서 여러개의 DB에 connection을 해야 하는 상황이다. springboot에서는 이를 어떻게 처리해야 할까? 약간의 설정을 추가해줌으로써 쉽게 가능하다.
application.yml 변경
AS-IS
spring:
datasource:
driver-class-name: oracle.jdbc.OracleDriver
url: jdbc:oracle:thin:@xx.xx.xx.xx:1521:OINGDADDY
username: oing
password: daddy
기존에는 기본 datasource와 sqlSessionFactory를 사용을 했었다. 따라서 이렇게만 설정해주면 어디서든 DataSource와 SqlSessionFactory를 주입받아 사용할 수 있었다. 하지만 다중 DB 연결을 하려면 이 부분에 대해 변경이 있어야 한다.
TO-BE
spring:
datasource-oracle:
driver-class-name: oracle.jdbc.OracleDriver
jdbc-url: jdbc:oracle:thin:@xx.xx.xx.xx:1521:OINGDADDY
username: oing
password: daddy
datasource-mysql:
driver-class-name: com.mysql.jdbc.Driver
jdbc-url: jdbc:mysql://xx.xx.xx.xx:3306/OINGDADDY
username: oing
password: daddy
이런식으로 기존의 application.yml에서 datasource 설정을 바꿔줘야 한다. spring.datasource 부분은 spring.custom_datasource_name 으로 변경을 해주고 url은 jdbc-url로 변경을 해준다. 필자는 기존에 사용하고 있던 oracle db에 추가로 mysql datasource를 추가하였다. 물론 mysql connector는 장착이 되어 있어야 한다.
PersistentConfig.java 변경
AS-IS
@Autowired
private DataSource dataSource;
@Autowired
private SqlSessionFactory sqlSessionFactory;
//@Bean
//public SqlSession sqlSession() {
// return new SqlSessionTemplate(sqlSessionFactory);
//}
@Bean
public CommonDao commonDao() throws Exception {
CommonDao commonDao = new CommonDao();
commonDao.setSqlSessionFactory(sqlSessionFactory);
return commonDao;
}
@Bean
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource);
}
기존에는 DB 관련 설정을 하는 java config 파일의 구성은 위와 같았다. 필자는 CommonDao라는 것을 만들어서 사용하고 있어서 CommonDao 기준으로 설명을 하겠다. 이것의 역할은 위에 주석으로 처리해놓은 SqlSessionTemplate과 유사하다.
TO-BE
@Autowired
private ApplicationContext applicationContext;
@Bean
@Qualifier("oracleDataSource")
@ConfigurationProperties(prefix = "spring.datasource-oracle")
public DataSource oracleDataSource() {
return DataSourceBuilder.create()
.type(HikariDataSource.class)
.build();
}
@Bean
@Qualifier("mysqlDataSource")
@ConfigurationProperties(prefix = "spring.datasource-mysql")
public DataSource mysqlDataSource() {
return DataSourceBuilder.create()
.type(HikariDataSource.class)
.build();
}
@Bean
@Primary
public SqlSessionFactory oracleSqlSessionFactory() throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(oracleDataSource());
factoryBean.setVfs(SpringBootVFS.class);
factoryBean.setConfigLocation(applicationContext.getResource("classpath:mybatis/mybatis-config.xml"));
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource[] resource = resolver.getResources("mybatis/oracle/**/*.xml");
factoryBean.setMapperLocations(resource);
return factoryBean.getObject();
}
@Bean
public SqlSessionFactory mysqlSqlSessionFactory() throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(mysqlDataSource());
factoryBean.setVfs(SpringBootVFS.class);
factoryBean.setConfigLocation(applicationContext.getResource("classpath:mybatis/mybatis-config.xml"));
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource[] resource = resolver.getResources("mybatis/mysql/**/*.xml");
factoryBean.setMapperLocations(resource);
return factoryBean.getObject();
}
@Bean
@Primary
public CommonDao commonDao() throws Exception {
CommonDao commonDao = new CommonDao();
commonDao.setSqlSessionFactory(oracleSqlSessionFactory());
return commonDao;
}
@Bean
@Qualifier("mysqlCommonDao")
public CommonDao mysqlCommonDao() throws Exception {
CommonDao commonDao = new CommonDao();
commonDao.setSqlSessionFactory(mysqlSqlSessionFactory());
return commonDao;
}
@Bean
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(oracleDataSource());
}
@Bean
public PlatformTransactionManager mysqlTransactionManager() {
return new DataSourceTransactionManager(mysqlDataSource());
}
기존에 기본으로 주입받아서 사용하던 DataSource와 SqlSessionFactory에 대한 재정의가 필요하다. 필요한 DB 연결수만큼 이런식으로 DataSource, SqlSessionFactory, SqlTemplate 등을 확장해서 만들어주면 된다. 필요에 따라서 DB별로 Config 파일을 분리하는것도 좋은 방법이다.
@ConfigurationProperties 부분에 warning이 뜬다면 이 글을 참조해서 지워주도록 하자. 여기에 들어가는 prefix에 해당하는 내용은 application.yml에서 정의했던 datasource property이다.
@Primary로 같은 우선순위로 있는 클래스가 여러개가 있을 시 그 중 가장 우선순위로 주입할 클래스 타입을 선택할 수 있다. 많이 사용되는 곳에 걸어주도록 하자.
@Qualifier는 @Autowired와 같이 쓰이며 여러개의 타입이 일치하는 bean객체가 있을 경우 @Qualifier 어노테이션의 유무를 확인한 후 조건에 만족하는 객체를 주입하게 된다.
Multi Datasource 사용법
@Autowired
@Qualifier("mysqlCommonDao")
private CommonDao mysqlCommonDao;
위의 설정을 기반으로 mysql을 사용할때는 이런식으로 사용하면 mysql datasource로 연결이 된다.
@Autowired
private CommonDao commonDao;
oracle을 사용할때는 기존과 동일한 모습으로 위와 같이 사용할 수 있다.
위에서도 언급했지만 필자는 CommonDao를 만들어서 사용중이고 이를 SqlSessionTemplate으로 대체해서 사용할 수 있다.
끝!
'Framework > Spring' 카테고리의 다른 글
Spring Boot Transaction Timeout 설정 및 기본값 (0) | 2021.09.02 |
---|---|
Springboot + Ehcache 초간단 설정 및 사용방법 (0) | 2021.08.26 |
Springboot @ConfigurationProperties warning 조치 (0) | 2021.08.04 |
Springboot application.yml (application.properties) 파일 분리방법 (0) | 2021.08.02 |
Spring BindingAwareModelMap argument type mismatch 오류 조치 (0) | 2021.07.15 |