Study/Spring Framework

[Spring Boot] 다중 데이터베이스 환경 구축 방법

jonghne 2022. 7. 15. 18:38

개요

회사 업무 중 Spring Boot 서버에서 2개의 서로 다른 DB에 접근해야 하는 업무가 생겨 다중 데이터베이스 환경을 구축하게 되었다.

 

다중 데이터베이스 접근 환경 구축 순서는 순서는 아래와 같다.

1. 패키지 구조 변경 (Mapper 인터페이스, xml파일 패키지로 감싸기)
2. 서버 설정파일에 DB 연결정보 작성
3. Config 파일 생성 및 수정

 

프로젝트 패키지 구조 변경

다중 DB를 사용할 때는 보통 Oracle, Mysql 과 같이 DBMS가 다른 케이스에 사용하기 때문에 쿼리 파일을 별도로 관리하는 것이 좋다 (패키지도 나누는 것이 관리하기 편하다)

 

아래와 같이 Mapper 인터페이스 파일을 관리하는 패키지와 실제 구현체인 xml 쿼리파일을 관리하는 패키지를 두개로 나눈다 

 

 

서버 설정파일에 DB 연결정보 작성

기존에는 spring 하위에 바로 datasource 설정이 되어있는데, 이 설정을 아래와 같은 구조로 두개로 나누어서 각각 DB 설정 정보를 기입한다.

 

 

DB Config 파일 생성 및 수정

Mybatis를 사용하려면 DataSource, SqlSessiontTemplate, SqlSessionFactory Bean 객체를 등록해야 한다.

 

다중 데이터 베이스를 사용하려면 데이터베이스마다 해당 작업을 진행해야 하는데, Spring의 Bean 관리 방법이 싱글톤을 사용하기 때문에 여러 DataSource 관련 Bean이 있으면 충돌난다.

 

그렇기 때문에 특정 데이터베이스의 config 파일에 @Primaery 어노테이션을 붙여서 Bean을 생성해주고, 그 외에 데이터베이스 설정 파일에는 @Qualifier 어노테이션 같은 걸로 지칭을 해줘야 한다.

 

그래서 나는 기존에 사용하던 DB 설정 파일에 Primary를 붙여서 사용하게끔 하고, 추가되는 DB 설정 파일에 @Qualifier 어노테이션을 붙여서 각각 설정했다.

 

 

✅ @Primary를 붙인 설정파일

 

 

✅ @Qualifier를 붙인 설정파일

 

 

DB Config 파일 작성 순서 요약

1번째. @Configuration 어노테이션을 붙여서 Spring Framework가 기동시 등록할수 있게 한다.

 

2번째. @MapperScan 어노테이션을 사용해서 사용할 Mapper 인터페이스 경로를 지정하고, sqlSessionFactoryRef로 어떤 sqlSessionFactory를 사용할건지 지정한다 !! (중요, sqlSessionFactoryRef 를 지정하지 않으면 충돌나서 그런건지 BindingException 떨어진다.)

 

3번째. 특정 DB 설정 파일에 @Primary 어노테이션을 붙여준다.

- Spring은 Bean 관리를 싱글톤으로 관리하기 때문에, dataSource가 여러개 있으면 어떤 Bean을 주입할지 모르기때문에 N개 중 1개 파일에는 @Primary 어노테이션을 붙여준다.

 

4번째. DataSource 메소드 작성

- 서버 설정 파일의 어떤 dataSource를 사용할건지 경로를 지정한다. (@ConfigurationProperties 어노테이션)

 

5번째. SqlSessionFactory 메소드 작성

- 메소드 인자로 DataSource를 받는데, 이때 @Qualifier 어노테이션을 사용해서 DataSource을 지정해서 충돌 안나게하기 (@Primary 붙인 파일은 예외)

- Mapper Xml 경로 알맞게 지정 (필자는 DB별로 폴더를 따로 나눠서 관리했기 때문에 각각 지정해줬다)

 

6번째. SqlSessionTemplate 메소드 작성

- 메소드 인자로 SqlSessionFactory를 받는데, 이때 @Qualifier 어노테이션을 사용해서 sqlSessionFactory를 지정해서 충돌 안나게하기 (@Primary 붙인 파일은 예외)

 

 

위와 같이 설정 한 다음 Service 단에서 각각의 Mapper를 사용해서 DB에 접근하면 된다.