hoony's web study

728x90
반응형

- 환경

OpenJDK 11

Kotlin

Gradle(kotlin)

SpringBoot 2.7.8

Mybatis

 

- 설정

우선, yml에서 프로퍼티 값을 미리 설정 해주도록 합니다.

[application.yml]

maindb:
  hikari:
    maximum-pool-size: 100
    pool-name: HikariPOOL [TEST - PrimaryDB]
  url: jdbc:mariadb://IP:PORT/DB?characterEncoding=UTF-8
  username: USERNAME
  password: PASSWORD
  driver-class-name: org.mariadb.jdbc.Driver
secondb:
  hikari:
    maximum-pool-size: 100
    pool-name: HikariPOOL [TEST - SecondDB]
  url: jdbc:mariadb://IP:PORT/DB?characterEncoding=UTF-8
  username: USERNAME
  password: PASSWORD
  driver-class-name: org.mariadb.jdbc.Driver

 

이렇게 두가지 DB에 대한 프로퍼티 값은 명시를 해주었습니다.

이제부턴, Configuration Kotlin 을 정의해주도록 해볼겁니다.

Database 정의 하는것 또한, 파일을 분리시켜 만들어보도록 할겁니다.

우선, 메인 DB부터 설정해주도록 하겠습니다.

 

[PrimaryDatabaseConfig.kt]

/**
 * 해당 클래스는 DataSource를 yml로 인한 자동적인 주입이 아닌, 임의적으로 주입시켜주기 위한 클래스이다.
 * Primary DB Setting
 * @MapperScan 어노테이션은, Mybatis에서 사용될 Repository와 SQL Mapper XML을 지정해주기 위한 세팅입니다.
 * @Primary 어노테이션을 통해, 해당 Bean이 주가 될 Config임을 명시해줍니다.
 */

@Configuration
@EnableTransactionManagement
@PropertySource("classpath:application.yml")
@MapperScan(
        basePackages = ["kr.ourcodelab.example.domain.**.repository.main"],
        sqlSessionFactoryRef = "sqlSessionFactory"
)
class MainDatabaseConfig {


    /**
     * Hikari DataSource Config을 멀티 데이터소스별로 적용시키기 위해 아래와같이 작성
     */
    @Primary
    @Bean
    @ConfigurationProperties("maindb")
    fun dataSourceProperties(): DataSourceProperties {
        return DataSourceProperties()
    }

    @Primary
    @Bean
    @ConfigurationProperties("maindb.hikari")
    fun dataSource(): HikariDataSource {
//        val dataSource = DataSourceBuilder.create().build()
//        return dataSource;
        return dataSourceProperties().initializeDataSourceBuilder().type(HikariDataSource::class.java).build()
    }

    @Primary
    @Bean
    fun transactionManager(
        @Qualifier("dataSource") dataSource: DataSource
    ): DataSourceTransactionManager {
        val trManager = DataSourceTransactionManager()
        trManager.dataSource = dataSource

        return trManager
    }

    @Primary
    @Bean
    fun sqlSessionFactory(
            @Qualifier("dataSource") dataSource: DataSource
    ): SqlSessionFactory? {
        var sqlSessionFactoryBean = SqlSessionFactoryBean()
        try {
            val mapperLocations = PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/main/**/*.xml")

            sqlSessionFactoryBean.setDataSource(dataSource)
            sqlSessionFactoryBean.setConfigLocation(PathMatchingResourcePatternResolver().getResource("classpath:mybatis/config/web/mybatis-config.xml"))
            sqlSessionFactoryBean.setMapperLocations(*mapperLocations)
            sqlSessionFactoryBean.setTypeAliasesPackage("kr.ourcodelab.example.domain.**.model")
        } catch (e: Exception) {
            throw e
        }
        return sqlSessionFactoryBean.`object`
    }

    @Primary
    @Bean
    fun sqlSessionTemplate(
            @Qualifier("sqlSessionFactory") sqlSessionFactory: SqlSessionFactory
    ): SqlSessionTemplate {
        return SqlSessionTemplate(sqlSessionFactory)
    }

}

 

 

[SecondDatabaseConfig.kt]

/**
 * 해당 클래스는 DataSource를 yml로 인한 자동적인 주입이 아닌, 임의적으로 주입시켜주기 위한 클래스이다.
 * Second DB Setting
 * @MapperScan 어노테이션은, Mybatis에서 사용될 Repository와 SQL Mapper XML을 지정해주기 위한 세팅입니다.
 */

@Configuration
@EnableTransactionManagement
@PropertySource("classpath:application.yml")
@MapperScan(
        basePackages = ["kr.ourcodelab.example.domain.**.repository.second"],
        sqlSessionFactoryRef = "secondSqlSessionFactory"
)
class MainDatabaseConfig {


    /**
     * Hikari DataSource Config을 멀티 데이터소스별로 적용시키기 위해 아래와같이 작성
     */
    @Bean
    @ConfigurationProperties("secondb")
    fun secondDataSourceProperties(): DataSourceProperties {
        return DataSourceProperties()
    }

    @Bean
    @ConfigurationProperties("secondb.hikari")
    fun secondDataSource(): HikariDataSource {
//        val dataSource = DataSourceBuilder.create().build()
//        return dataSource;
        return secondDataSourceProperties().initializeDataSourceBuilder().type(HikariDataSource::class.java).build()
    }

    @Bean
    fun secondTransactionManager(
        @Qualifier("secondDataSource") dataSource: DataSource
    ): DataSourceTransactionManager {
        val trManager = DataSourceTransactionManager()
        trManager.dataSource = dataSource

        return trManager
    }

    @Bean
    fun secondSqlSessionFactory(
            @Qualifier("secondDataSource") dataSource: DataSource
    ): SqlSessionFactory? {
        var sqlSessionFactoryBean = SqlSessionFactoryBean()
        try {
            val mapperLocations = PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/second/**/*.xml")

            sqlSessionFactoryBean.setDataSource(dataSource)
            sqlSessionFactoryBean.setConfigLocation(PathMatchingResourcePatternResolver().getResource("classpath:mybatis/config/web/mybatis-config.xml"))
            sqlSessionFactoryBean.setMapperLocations(*mapperLocations)
            sqlSessionFactoryBean.setTypeAliasesPackage("kr.ourcodelab.example.domain.**.model")
        } catch (e: Exception) {
            throw e
        }
        return sqlSessionFactoryBean.`object`
    }

    @Bean
    fun secondSqlSessionTemplate(
            @Qualifier("secondSqlSessionFactory") sqlSessionFactory: SqlSessionFactory
    ): SqlSessionTemplate {
        return SqlSessionTemplate(sqlSessionFactory)
    }

}

 

위의 예제 소스를 보시면, Primary와 Second의 설정이 미묘하게 차이가 나는것을 확인하실 수 있습니다.

 

@MapperScan 어노테이션을 보시면, 둘의 basePackage 경로를 분리하여 충돌이 나지않게

미리 방지해둔 점과, SqlSessionFactory 또한 Mapper XML의 경로를 분리하여 설정 후 나누어서

명시해주었습니다.

Mybatis를 사용하지 않으실 경우, SqlSessionFactory와 SqlSessionTemplate에 대한 정의가

불필요하지만, 위의 경우 mybatis를 사용하는것을 기준으로 작성되었습니다.

 

이렇게, 어렵지않게 다중 데이터소스를 정의해주고 사용하는 방법에 대해 알아보았습니다.

감사합니다.

728x90

공유하기

facebook twitter kakaoTalk kakaostory naver band
loading