TokyoAJ

도쿄아재

SPRINGBOOT 2025.04.05

Spring Boot에서 MyBatis 다중 DB 구성 방법 – Master/Slave 실무 예제 기준

대부분의 프로젝트에서는 하나의 데이터베이스만 사용하지만,

읽기/쓰기 분리(Master/Slave) 또는 비즈니스별로 다른 DB를 사용할 필요가 있는 상황도 종종 발생합니다.

이 글에서는 Spring Boot에서 MyBatis로 다중 데이터베이스를 설정하는 방법을

실제 실무 환경에 맞춰 Master / Slave 구조를 기준으로 상세히 정리해봅니다.


사용 환경 예시

  1. Spring Boot 3.x
  2. MyBatis-Spring-Boot-Starter
  3. MySQL 또는 MariaDB
  4. Maven


기본 디렉토리 구조

src/
├── main/
│ ├── java/
│ │ └── com/example/
│ │ ├── config/ ← DB 설정 클래스
│ │ └── mapper/
│ │ ├── master/ ← Master Mapper
│ │ └── slave/ ← Slave Mapper
│ └── resources/
│ └── mapper/
│ ├── master/ ← Master XML
│ └── slave/ ← Slave XML


1. application.yml 설정

spring:
datasource:
master:
url: jdbc:mysql://localhost:3306/master_db
username: root
password: root123
driver-class-name: com.mysql.cj.jdbc.Driver

slave:
url: jdbc:mysql://localhost:3306/slave_db
username: root
password: root123
driver-class-name: com.mysql.cj.jdbc.Driver


2. Master DB 설정 클래스

@Configuration
@Primary
@MapperScan(basePackages = "com.example.mapper.master", sqlSessionFactoryRef = "masterSqlSessionFactory")
public class MasterDBConfig {

@Bean(name = "masterDataSource")
@Primary
@ConfigurationProperties(prefix = "spring.datasource.master")
public DataSource masterDataSource() {
return DataSourceBuilder.create().build();
}

@Bean(name = "masterSqlSessionFactory")
@Primary
public SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource") DataSource ds, ApplicationContext ctx) throws Exception {
SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
factory.setDataSource(ds);
factory.setMapperLocations(ctx.getResources("classpath:mapper/master/**/*.xml"));
return factory.getObject();
}

@Bean(name = "masterSqlSessionTemplate")
@Primary
public SqlSessionTemplate masterSqlSessionTemplate(@Qualifier("masterSqlSessionFactory") SqlSessionFactory sf) {
return new SqlSessionTemplate(sf);
}
}


3. Slave DB 설정 클래스

@Configuration
@MapperScan(basePackages = "com.example.mapper.slave", sqlSessionFactoryRef = "slaveSqlSessionFactory")
public class SlaveDBConfig {

@Bean(name = "slaveDataSource")
@ConfigurationProperties(prefix = "spring.datasource.slave")
public DataSource slaveDataSource() {
return DataSourceBuilder.create().build();
}

@Bean(name = "slaveSqlSessionFactory")
public SqlSessionFactory slaveSqlSessionFactory(@Qualifier("slaveDataSource") DataSource ds, ApplicationContext ctx) throws Exception {
SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
factory.setDataSource(ds);
factory.setMapperLocations(ctx.getResources("classpath:mapper/slave/**/*.xml"));
return factory.getObject();
}

@Bean(name = "slaveSqlSessionTemplate")
public SqlSessionTemplate slaveSqlSessionTemplate(@Qualifier("slaveSqlSessionFactory") SqlSessionFactory sf) {
return new SqlSessionTemplate(sf);
}
}


4. Mapper 분리 예시

Master Mapper

package com.example.mapper.master;

@Mapper
public interface UserMapper {
void insertUser(User user);
}

Slave Mapper

package com.example.mapper.slave;

@Mapper
public interface UserReadMapper {
User selectUserById(Long id);
}

XML 파일은 resources/mapper/master/, resources/mapper/slave/ 디렉토리에 배치


5. Transaction 설정 (선택)

각 DB에 대해 트랜잭션 설정이 필요하다면 아래처럼 구성합니다:

@Bean(name = "masterTransactionManager")
@Primary
public DataSourceTransactionManager masterTransactionManager(@Qualifier("masterDataSource") DataSource ds) {
return new DataSourceTransactionManager(ds);
}


@Bean(name = "slaveTransactionManager")
public DataSourceTransactionManager slaveTransactionManager(@Qualifier("slaveDataSource") DataSource ds) {
return new DataSourceTransactionManager(ds);
}


실무 팁

  1. @Primary는 기본 DB 설정으로 지정할 때 꼭 필요합니다.
  2. @MapperScan에 sqlSessionFactoryRef를 정확히 지정해야 연결이 꼬이지 않습니다.
  3. application.yml에서 spring.datasource.master/slave 설정을 각각 분리해야 합니다.
  4. 커스텀 쿼리는 XML 파일을 master/ 또는 slave/ 디렉토리에 명확히 분리해 주세요.


자주 묻는 질문

Q. JPA랑 같이 써도 되나요?

가능합니다. 단, MyBatis와 JPA의 트랜잭션 관리 방식이 다르기 때문에 @Transactional 적용 범위를 명확히 해야 합니다.

Q. 여러 Slave를 동적으로 로드밸런싱 할 수 있나요?

기본 MyBatis만으로는 어렵지만, Spring Cloud + RoutingDataSource 또는 ShardingSphere 같은 프레임워크를 쓰면 가능합니다.


마무리

MyBatis 기반 프로젝트에서 Master/Slave DB 분리는 트래픽 최적화와 장애 분산을 위해 꼭 필요한 구조입니다.

Spring Boot에서는 다중 DB 설정을 분리하고 @MapperScanSqlSessionFactory를 명확히 설정하면

생각보다 매우 쉽게 다중 DB 환경을 구축할 수 있습니다.




댓글

dnwn**************** 2025.04.05 08:23:43
좋은내용 감사합니다. 자주 들어올께요.