티스토리 뷰
하나의 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 |