티스토리 뷰

반응형

이번에는 두개의 데이터베이스를 사용할때 DataSource를 설정하는 방법을 알아보겠습니다.

하나의 DB에 대한 설정이 필요하신 경우 이글을 읽어보시면 도움을 받으실 수 있습니다.

1. 환경설정

build.gradle.kts

// Spring Data JPA 스타터 추가
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
// MySQL Connector 추가
runtimeOnly("mysql:mysql-connector-java:8.0.22")

 

 

 

2. DB 프로퍼티 설정

2개 이상의 데이터베이스를 사용할 경우에는 프로퍼티 설정도 각각 설정해주어야 합니다.

spring:
  datasource-Memo:
    driver-class-name: com.mysql.cj.jdbc.Driver
    jdbcUrl: "jdbc:mysql://localhost:3306/Memo?autoReconnect=true&useUnicode=true&serverTimezone=Asia/Seoul"
    username: root
    password: 1234
  datasource-card:
    driver-class-name: com.mysql.cj.jdbc.Driver
    jdbcUrl: "jdbc:mysql://localhost:3306/card?autoReconnect=true&useUnicode=true&serverTimezone=Asia/Seoul"
    username: root
    password: 1234
  jpa:
    database: mysql
    database-platform: org.hibernate.dialect.MySQL8Dialect
    properties:
      hibernate:
        storage_engine: innodb
        format_sql: true
        use_sql_comments: true
    hibernate:
      ddl-auto: none
    open-in-view: false
    show_sql: true

 

3. Configuration 설정

그러면 Memo와 card 각각의 데이터베이스 설정을 추가해주겠습니다.

JPA를 사용하는 환경이라면 총 3개의 설정을 정의해줘야 합니다.

  • DataSource
  • EntityManagerFactory(userEntityManager)
  • TransactionManager(userTransactionManager)

 

MemoDataSourceConfiguration

@Configuration
@EnableJpaRepositories(
    basePackages = ["com.example.springdatasource"],
    entityManagerFactoryRef = "memoEntityManager",
    transactionManagerRef = "memoTransactionManager",
)
class MemoDataSourceConfiguration {

    @Primary
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource-memo")
    fun memoDataSource(): DataSource {
        return DataSourceBuilder.create()
            .build()
    }

    @Primary
    @Bean
    fun memoEntityManager(): LocalContainerEntityManagerFactoryBean =
        (LocalContainerEntityManagerFactoryBean()).apply {
            dataSource = memoDataSource()
            setPackagesToScan("com.example.springdatasource")
            jpaVendorAdapter = HibernateJpaVendorAdapter()
        }

    @Primary
    @Bean
    fun memoTransactionManager() = JpaTransactionManager(memoEntityManager().`object`!!)
}

 

CardDataSourceConfiguration

@Configuration
@EnableJpaRepositories(
    basePackages = ["com.example.springdatasource"],
    entityManagerFactoryRef = "cardEntityManager",
    transactionManagerRef = "cardTransactionManager",
)
class CardDataSourceConfiguration {

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource-card")
    fun cardDataSource(): DataSource {
        return DataSourceBuilder.create()
            .build()
    }

    @Bean
    fun cardEntityManager(): LocalContainerEntityManagerFactoryBean =
        (LocalContainerEntityManagerFactoryBean()).apply {
            dataSource = cardDataSource()
            setPackagesToScan("com.example.springdatasource")
            jpaVendorAdapter = HibernateJpaVendorAdapter()
        }

    @Bean
    fun cardTransactionManager() = JpaTransactionManager(cardEntityManager().`object`!!)
}

필요한 3개의 설정을 모두 완료했다면 설정은 끝입니다.

 

4. Spring Boot AutoConfiguration

Spring Boot의 AutoConfiguration을 사용하면 좀 더 간단하게 configuration을 설정할 수 있습니다.

다만 datasource는 직접 정의해주어야 합니다.

datasource는 직접 정의해주지 않으면 AutoConfiguration을 할때 자동으로 어떤 datasource(Memo or card)를 주입해야 하는지 알 수 없기 때문입니다.

 

MemoDataSourceConfiguration

@Configuration
@EnableJpaRepositories(
    basePackages = ["com.example.springdatasource"],
    entityManagerFactoryRef = "memoEntityManager",
    transactionManagerRef = "memoTransactionManager",
)
class MemoDataSourceConfiguration {

    @Primary
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource-memo")
    fun memoDataSource(): DataSource {
        return DataSourceBuilder.create()
            .build()
    }
}

 

CardDataSourceConfiguration

@Configuration
@EnableJpaRepositories(
    basePackages = ["com.example.springdatasource"],
    entityManagerFactoryRef = "cardEntityManager",
    transactionManagerRef = "cardTransactionManager",
)
class CardDataSourceConfiguration {

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource-card")
    fun cardDataSource(): DataSource {
        return DataSourceBuilder.create()
            .build()
    }
}

 

5. 실제 사용

// Memo 서비스 로직
@Service
@Transactional("memoTransactionManager")
class MemoService {
}

// Card 서비스 로직
@Service
@Transactional("cardTransactionManager")
class CardService {
}

실제 사용시에는 트랜잭션을 사용하는 시점에 TransactionManager를 지정해서 사용하면 됩니다.

만약 TransactionManager를 지정하지 않는다면 위에서 memoTransactionManager에 @Primary 어노테이션을 선언했기 때문에 memoTransactionManager가 우선적으로 적용이 될 것입니다.

 

 

참고자료

https://www.baeldung.com/spring-data-jpa-multiple-databases

반응형
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함