본문 바로가기
Backend/Spring

[Spring] 스프링 Mybatis 다중 디비 연결 (디비 연결 2개 이상)

by 그적 2022. 4. 18.

 

프로젝트 폴더 구조는 다음과 같다.

 

 

Mybatis를 이용해 4개의 file, netstat, process, register 데이터베이스를 연동시킬 예정이다.

file, netstat, process, register 패키지 안에 domain class 파일, config class 파일, mapper interface 파일을 만들어줬다.

 

domain 파일은 데이터베이스에 전달해줄 디폴트 값이며, config 파일은 데이터베이스 설정 파일이고, mapper 인터페이스 파일은 실제 쿼리문이 담긴 mapper.xml을 추상화시키기 위한 파일이다.

 

제일 중요한 파일은 당연히 각 데이터베이스의 config 파일이다.

// RegisterConfig.class (register 데이터베이스 config 파일)

@Configuration
@EnableTransactionManagement
@MapperScan(value = " ...(프로젝트 구조명)... ",
            sqlSessionFactoryRef = "registerFactory",
            sqlSessionTemplateRef = "registerSession")
public class RegisterConfig {

    @Autowired
    private ApplicationContext applicationContext;

    @Primary
    @Bean(name = "registerDataSource")
    @ConfigurationProperties(prefix="spring.register.datasource4")
    public DataSource registerDataSource(){
        return DataSourceBuilder.create().build();
    }

    @Primary
    @Bean(name = "registerFactory")
    public SqlSessionFactory registerFactory(@Autowired @Qualifier("registerDataSource") DataSource registerDataSource) throws Exception{
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(registerDataSource);
        sqlSessionFactoryBean.setConfigLocation(applicationContext.getResource("classpath:mybatis/mybatis-config.xml"));
        sqlSessionFactoryBean.setVfs(SpringBootVFS.class);
        sqlSessionFactoryBean.setMapperLocations(applicationContext.getResource("classpath:mapper/registerMapper.xml"));

        return sqlSessionFactoryBean.getObject();
    }

    @Primary
    @Bean(name = "registerSession")
    public SqlSessionTemplate registerSqlSession(@Autowired @Qualifier("registerFactory") SqlSessionFactory registerFactory) throws Exception{
        return new SqlSessionTemplate(registerFactory);
    }

    @Primary
    @Bean(name="registerTransaction")
    public DataSourceTransactionManager registerTransactionManager(@Autowired @Qualifier("registerDataSource") DataSource registerDataSource){
        return new DataSourceTransactionManager(registerDataSource);
    }


}

 

다중 디비를 연결할 때 중요한 부분만 짚으면서 넘어가면, MapperScan 어노테이션에서 sqlSessionFactoryRef와 sqlSessionTemplateRef 를 반드시 작성해주어야 한다. Bean name이나 @Qualifier 어노테이션으로 설정해둔 네임을 입력해준다.

또한 반드시 하나의 데이터베이스에는 @Primary 어노테이션을 붙여주어야 한다. 그래야 @Autowired를 사용할 때 여러 개의 데이터베이스에서 우선순위를 갖는 @Primary 어노테이션이 붙여져 있는 데이터베이스로 연동되거나 @Qualifier로 의존성이 주입된 빈으로 연동된다.

 

- DataSource : application.yml 파일이나 application.properties 파일에 정의된 내용과 연동됨.

- SqlSessionFactory : 해당 데이터베이스의 Mapper 위치 설정과 SqlSession 객체를 생성함.

- SqlSessionTemplate : 스프링에서 Mybatis를 사용하기 위해 SqlSessionTemplate를 사용함.

- DataSourceTransactionManager : 트랜젝션에서 예외가 발생하면 롤백되는 기능을 가짐.

 

DataSource를 정의할 때 ConfigurationProperties 어노테이션을 이용해 yml 파일에 정의된 내용과 연결시킬 수 있도록 올바른 경로를 설정해둔다. (아래에 적어둔 application.yml 파일을 확인하면서 설정하자.)

 

// RegisterDBMapper.interface (mapper 인터페이스 파일)

@Mapper
@Resource(name="registerFactory")
public interface RegisterDBMapper {
  .. (mapper 내용) ..
}

 

// registerMapper.xml (resources 폴더에 존재)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="(프로젝트 경로).register.RegisterDBMapper">
  .. (쿼리 내용) ..
</mapper>

 

 

 

// FileConfig.class (file 데이터베이스 config 파일)

:  DataSource에서 @ConfigurationProperties 어노테이션을 이용해 데이터베이스를 사용할 때의 설정과 연결해준다.

@Configuration
@EnableTransactionManagement
@MapperScan(basePackages = " ...(프로젝트 구조명)... ",
            sqlSessionFactoryRef = "fileFactory",
            sqlSessionTemplateRef = "fileSession")
public class FileConfig {

    @Autowired
    private ApplicationContext applicationContext;

    @Bean(name = "fileDataSource")
    @ConfigurationProperties(prefix = "spring.file.datasource1")
    public DataSource fileDataSource(){
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "fileFactory")
    public SqlSessionFactory fileFactory(@Autowired @Qualifier("fileDataSource") DataSource fileDataSource) throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(fileDataSource);
        sqlSessionFactoryBean.setConfigLocation(applicationContext.getResource("classpath:mybatis/mybatis-config.xml"));
        sqlSessionFactoryBean.setVfs(SpringBootVFS.class);
        sqlSessionFactoryBean.setMapperLocations(applicationContext.getResource("classpath:mapper/fileMapper.xml"));

        return sqlSessionFactoryBean.getObject();
    }

    @Bean(name = "fileSession")
    public SqlSessionTemplate fileSqlSession(@Autowired @Qualifier("fileFactory") SqlSessionFactory fileFactory) throws Exception {
        return new SqlSessionTemplate(fileFactory);
    }

    @Bean(name = "fileTransaction")
    public DataSourceTransactionManager fileTransactionManager(@Autowired @Qualifier("fileDataSource") DataSource fileDataSource){
        return new DataSourceTransactionManager(fileDataSource);
    }


}

 

// FileDBMapper.interface (mapper 인터페이스 파일)

@Mapper
@Resource(name="fileFactory")
public interface FileDBMapper {
  .. (mapper 내용) ..
}

 

// fileMapper.xml (resources 폴더에 존재)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="(프로젝트 경로).file.FileDBMapper">
  .. (쿼리 내용) ..
</mapper>

 

 

(netstat 데이터베이스와 process 데이터베이스도 위의 구조와 동일함)

// application.yml 파일

: 데이터베이스 별로 datasource명 및 설정을 다르게 주입시킬 수 있다.

spring:
  h2:
    console:
      enabled: true
      path: /h2-console

  register:
    datasource4:
      jdbc-url: jdbc:h2:mem://localhost/~/register
      driver-class-name: org.h2.Driver
      username: sa
      password:

  file:
    datasource1:
      jdbc-url: jdbc:h2:mem://localhost/~/file
      driver-class-name: org.h2.Driver
      username: sa
      password:

  netstat:
    datasource2:
      jdbc-url: jdbc:h2:mem://localhost/~/netstat
      driver-class-name: org.h2.Driver
      username: sa
      password:

  process:
    datasource3:
      jdbc-url: jdbc:h2:mem://localhost/~/process
      driver-class-name: org.h2.Driver
      username: sa
      password:

 

 

 

댓글