티스토리 뷰

하나의 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으로 대체해서 사용할 수 있다. 

 

끝!

댓글
최근에 올라온 글
최근에 달린 댓글
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31