본문 바로가기
Kotlin

[Querydsl] 멀티 DB(Multi DB) 설정 하기, DB 2개 이상 연결

by 고체물리학 2023. 7. 17.

1. application.yml 에 Datasource 추가

 

spring:
  datasource:
    driverClassName: org.mariadb.jdbc.Driver
    url: jdbc:mariadb://localhost:3306/{DB명}
    username: {DB user}
    password: {DB password}

  second-datasource:
    driverClassName: org.mariadb.jdbc.Driver
    url: jdbc:mariadb://localhost:3306/{DB명}
    username: {DB user}
    password: {DB password}

 

2. DataSource Configuration

1) 첫 번째 DB 설정

 

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
    basePackages = ["패키지1","패기지2"],//첫번째 DB 패키지의 배열
    entityManagerFactoryRef = "entityManagerFactory", //EntityManager이름
    transactionManagerRef = "transactionManager"
)
class DatasourceConfig {
    @Bean
    @Primary
    @ConfigurationProperties("spring.datasource") // application.properties에 작성된 DB와 관련된 설정 값
    fun DatasourceProperties(): DataSourceProperties {
        return DataSourceProperties()
    }

    @Bean
    @Primary
    @ConfigurationProperties("spring.datasource.configuration") // DB와 관련된 설정값들의 접두사에 .configuration을 붙여준다.
    fun primaryDatasource(): DataSource {
        return DatasourceProperties().initializeDataSourceBuilder().type(HikariDataSource::class.java).build()
    }

    @Bean(name = ["entityManagerFactory"])
    @Primary
    fun entityManagerFactory(builder: EntityManagerFactoryBuilder): LocalContainerEntityManagerFactoryBean {
        val dataSource: DataSource = primaryDatasource()
        LocalContainerEntityManagerFactoryBean().setPackagesToScan()
        return builder.dataSource(dataSource).packages("패키지1","패키지2") // 첫번째 DB와 관련된 엔티티들이 있는 패키지(폴더) 경로
            .persistenceUnit("entityManager").build()
    }

    @Bean(name = ["transactionManager"])
    @Primary
    fun transactionManager(
        @Qualifier("entityManagerFactory") localContainerEntityManagerFactoryBean: LocalContainerEntityManagerFactoryBean
    ): PlatformTransactionManager {
        return JpaTransactionManager(localContainerEntityManagerFactoryBean.getObject()!!)
    }

}

 

첫 번째 DB의 Bean에는 @Primay를 붙여줘야 빈을 찾을 수 있다

 

원래 EntityManager이름 앞에 단어를 붙였었는데 아래 에러처럼 빈을 계속 못 찾아서 첫 번째 DB의 entityManagerFactoryRef, transactionManagerRef를 기본 이름으로 설정했다

required a bean named 'entityManagerFactory' that could not be found. 

 

2) 두 번째 DB 설정

 

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
    basePackages = ["패키지"],
    entityManagerFactoryRef = "secondEntityManagerFactory",
    transactionManagerRef = "secondTransactionManager"
)
class SecondDatasourceConfig {
    @Bean
    @ConfigurationProperties("spring.second-datasource")
    fun secondDatasourceProperties(): DataSourceProperties {
        return DataSourceProperties()
    }

    @Bean
    @ConfigurationProperties("spring.second-datasource.configuration")
    fun secondDatasource(): DataSource {
        return secondDatasourceProperties().initializeDataSourceBuilder().type(HikariDataSource::class.java).build()
    }

    @Bean(name = ["secondEntityManagerFactory"])
    fun secondEntityManagerFactory(builder: EntityManagerFactoryBuilder): LocalContainerEntityManagerFactoryBean {
        val dataSource = secondDatasource()
        return builder.dataSource(dataSource).packages("패키지").persistenceUnit("secondEntityManager").build()
    }

    @Bean(name = ["secondTransactionManager"])
    fun secondTransactionManager(
        @Qualifier("secondEntityManagerFactory") localContainerEntityManagerFactoryBean: LocalContainerEntityManagerFactoryBean
    ): PlatformTransactionManager {
        return JpaTransactionManager(localContainerEntityManagerFactoryBean.getObject()!!)
    }


}

 

 

3. Bean 등록

 

@Configuration
@EnableConfigurationProperties
class AppConfig(    /* JPA 관련 설정 */
        @PersistenceContext(unitName = "entityManager")
        val entityManager: EntityManager,
        @PersistenceContext(unitName = "secondEntityManager")
        val secondEntityManager: EntityManager
) {

    /* QueryDsl 관련 설정 */
    @Primary
    @Bean
    fun EntityManager(): JPAQueryFactory {
        return JPAQueryFactory(entityManager)
    }

    @Bean
    @Qualifier("secondQueryFactory")
    fun secondQueryFactory(): JPAQueryFactory {
        return JPAQueryFactory(secondEntityManager)
    }
}

 

QueryDsl을 사용하려면 @Primary가 주입된 Bean은 따로 설정 없이 사용할 수 있고 두번째 DB는 설정한 @Qualifirer("secondQueryFactory")를 사용하여 찾을 수 있게 한다

 

 

 

 

반응형

댓글