[java] MyBatis에서 다중 데이터소스 처리

MyBatis는 자바 기반의 ORM(Object-Relational Mapping) 프레임워크로서, 데이터베이스와의 상호 작용을 쉽게 구현할 수 있도록 도와줍니다. MyBatis를 사용하여 다중 데이터소스를 처리하는 방법에 대해 알아보겠습니다.

다중 데이터소스 구성

다중 데이터소스를 처리하기 위해서는 여러 개의 데이터소스를 구성해야 합니다. 각 데이터소스마다 별도의 설정을 해주어야 합니다. 예를 들어, db1db2라는 두 개의 데이터베이스가 있다고 가정해봅시다.

<environments default="db1">
  <environment id="db1">
    <transactionManager type="JDBC"/>
    <dataSource type="POOLED">
      <property name="driver" value="com.mysql.jdbc.Driver"/>
      <property name="url" value="jdbc:mysql://localhost:3306/db1"/>
      <property name="username" value="username"/>
      <property name="password" value="password"/>
    </dataSource>
  </environment>

  <environment id="db2">
    <transactionManager type="JDBC"/>
    <dataSource type="POOLED">
      <property name="driver" value="com.mysql.jdbc.Driver"/>
      <property name="url" value="jdbc:mysql://localhost:3306/db2"/>
      <property name="username" value="username"/>
      <property name="password" value="password"/>
    </dataSource>
  </environment>
</environments>

위의 예제에서는 db1db2라는 두 개의 데이터소스를 POOLED 타입으로 설정하였습니다. driver, url, username, password는 각 데이터베이스에 맞게 설정해주어야 합니다.

다중 데이터소스 사용

다중 데이터소스를 사용하기 위해서는 SqlSessionFactorySqlSessionTemplate을 커스터마이징하여 각 데이터소스에 맞는 SqlSessionFactory를 생성해주어야 합니다.

@Configuration
public class MyBatisConfig {

    @Bean(name = "db1SqlSessionFactory")
    public SqlSessionFactory db1SqlSessionFactory(@Qualifier("db1DataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        return sqlSessionFactoryBean.getObject();
    }

    @Bean(name = "db2SqlSessionFactory")
    public SqlSessionFactory db2SqlSessionFactory(@Qualifier("db2DataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        return sqlSessionFactoryBean.getObject();
    }

    @Bean(name = "db1SessionTemplate")
    public SqlSessionTemplate db1SessionTemplate(@Qualifier("db1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

    @Bean(name = "db2SessionTemplate")
    public SqlSessionTemplate db2SessionTemplate(@Qualifier("db2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

}

위의 예제에서는 db1db2를 각각 SqlSessionFactorySqlSessionTemplate으로 생성하였습니다. 각각의 SqlSessionFactory@Qualifier 어노테이션을 사용하여 해당 데이터소스에 맞게 지정해주어야 합니다.

다중 데이터소스 사용 예제

마지막으로, 다중 데이터소스를 실제로 사용하는 예제를 살펴보겠습니다. 각각의 데이터소스에 대한 Mapper 인터페이스를 생성하고, @Mapper 어노테이션을 사용하여 매핑해주어야 합니다.

@Mapper
public interface Db1Mapper {

    List<Db1Data> getAllData();

}
@Mapper
public interface Db2Mapper {

    List<Db2Data> getAllData();

}

위의 예제에서는 Db1MapperDb2Mapper라는 두 개의 Mapper 인터페이스를 생성하였습니다. 각각의 인터페이스에는 해당 데이터소스에 대한 데이터를 조회하는 메서드를 작성해주어야 합니다.

@Service
public class DataService {

    @Autowired
    @Qualifier("db1SessionTemplate")
    private SqlSessionTemplate db1SessionTemplate;

    @Autowired
    @Qualifier("db2SessionTemplate")
    private SqlSessionTemplate db2SessionTemplate;

    public List<Db1Data> getDb1Data() {
        Db1Mapper db1Mapper = db1SessionTemplate.getMapper(Db1Mapper.class);
        return db1Mapper.getAllData();
    }

    public List<Db2Data> getDb2Data() {
        Db2Mapper db2Mapper = db2SessionTemplate.getMapper(Db2Mapper.class);
        return db2Mapper.getAllData();
    }

}

위의 예제에서는 DataService 클래스에 SqlSessionTemplate을 각 데이터소스에 맞게 주입받아 사용하고 있습니다. getDb1DatagetDb2Data 메서드에서 각각의 데이터소스에 대한 Mapper 인터페이스를 사용하여 데이터를 조회하고 있습니다.

이처럼 MyBatis를 사용하여 다중 데이터소스를 처리할 수 있습니다. 다중 데이터소스를 사용하면 여러 개의 데이터베이스에 대한 작업을 손쉽게 처리할 수 있으며, 코드의 재사용성과 유지보수성을 높일 수 있습니다.

참고 자료