[Querydsl] 멀티 DB (Multi DB) 연결, 설정하기
1. application.yml에 데이터소스 추가하기
Spring Boot 프로젝트에서 두 개의 데이터베이스를 사용하기 위해 application.yml
파일에 각각의 데이터소스를 정의해줍니다.
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. 데이터소스 설정
1) 첫 번째 데이터베이스 설정
기본 데이터베이스 설정을 위해 @Primary
어노테이션을 사용해야 하며, 관련된 설정을 아래와 같이 구성합니다.
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
basePackages = ["패키지1", "패기지2"],
entityManagerFactoryRef = "entityManagerFactory",
transactionManagerRef = "transactionManager"
)
class DatasourceConfig {
@Bean
@Primary
@ConfigurationProperties("spring.datasource")
fun datasourceProperties(): DataSourceProperties {
return DataSourceProperties()
}
@Bean
@Primary
@ConfigurationProperties("spring.datasource.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()
return builder
.dataSource(dataSource)
.packages("패키지1", "패기지2")
.persistenceUnit("entityManager")
.build()
}
@Bean(name = ["transactionManager"])
@Primary
fun transactionManager(
@Qualifier("entityManagerFactory") factory: LocalContainerEntityManagerFactoryBean
): PlatformTransactionManager {
return JpaTransactionManager(factory.getObject()!!)
}
}
첫 번째 데이터소스의 빈에는 @Primary
를 꼭 붙여야 빈 충돌 없이 제대로 주입됩니다.
처음에는 entityManagerFactoryRef
와 transactionManagerRef
에 접두어를 붙여 사용했지만, 아래와 같은 에러가 발생했습니다:
required a bean named 'entityManagerFactory' that could not be found.
이후 기본 이름으로 설정하면서 문제를 해결했습니다.
2) 두 번째 데이터베이스 설정
보조 DB는 별도의 설정 클래스를 만들어 관리하며, EntityManagerFactory
와 TransactionManager
이름도 달리 지정합니다.
@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") factory: LocalContainerEntityManagerFactoryBean
): PlatformTransactionManager {
return JpaTransactionManager(factory.getObject()!!)
}
}
3. Bean 등록 및 QueryDsl 설정
QueryDsl을 사용하기 위해 EntityManager
를 주입받고, 각각에 대한 JPAQueryFactory
빈을 등록해줍니다.
@Configuration
@EnableConfigurationProperties
class AppConfig(
@PersistenceContext(unitName = "entityManager")
val entityManager: EntityManager,
@PersistenceContext(unitName = "secondEntityManager")
val secondEntityManager: EntityManager
) {
@Primary
@Bean
fun queryFactory(): JPAQueryFactory {
return JPAQueryFactory(entityManager)
}
@Bean
@Qualifier("secondQueryFactory")
fun secondQueryFactory(): JPAQueryFactory {
return JPAQueryFactory(secondEntityManager)
}
}
@Primary
가 적용된 기본 JPAQueryFactory
는 별도 지정 없이 사용할 수 있으며, 두 번째 DB에 대한 QueryDsl은 @Qualifier("secondQueryFactory")
를 통해 명시적으로 주입하여 사용합니다.
댓글
댓글 쓰기