Spring Boot 다중 Database 구성 (JPA, PostgreSQL, MySQL)

Record For a Better Life ·2023년 12월 15일
1

스프링부트 내에서 Database를 구성할 때 보통 application.yml에서 다음과 같이 작성한다.

spring:
  datasource:
    driver-class-name: org.postgresql.Driver
    url: jdbc:postgresql://localhost:5432/dbname
    platform: postgres
    username: username
    password: password

대부분의 작은 프로젝트에서는 이렇게 단일 DB로 구성되지만, 여러 개의 DB로 나누어 관리하거나 외부 DB를 참조해야 할 경우 다중 데이터베이스 구성이 필요하다.

다중 Database 구성

나는 PostgreSQL 로컬 DB 하나와, 외부에서 참조할 PostgreSQL, MySQL DB 하나씩 연동이 필요한 상황이었다.
먼저 각각의 구성 정보를 db1, db2, db3과 같이 나누어 담아준다.

application.yml

  # 다중 Database 구성
  datasource:
    db1:
      jdbcUrl: jdbc:postgresql://localhost:5432/dbname
      username: username
      password: password
      driverClassName: org.postgresql.Driver
    db2:
      jdbcUrl: jdbc:postgresql://localhost:5432/dbname
      username: username
      password: password
      driverClassName: org.postgresql.Driver
    db3:
      dialect: org.hibernate.dialect.MySQLDialect
      jdbcUrl: jdbc:mysql://localhost:5432/dbname
      username: username
      password: password
      driverClassName: com.mysql.jdbc.Driver

단일 DB 구성에서는 yaml파일을 작성하면 프로젝트 내에서 자동으로 연동되지만, 다중 DB는 이 yaml파일 내의 정보를 이용해서 별도로 Config파일을 구성해주어야 한다.

Db1Config

@Configuration
@EnableJpaRepositories(
        basePackages = "com.example.test.domain",
        entityManagerFactoryRef = "db1EntityManagerFactory",
        transactionManagerRef = "db1TransactionManager"
)
public class Db1Config {
    @Primary
    @Bean(name = "db1DataSource")
    @ConfigurationProperties(prefix = "spring.datasource.db1")
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }

    @Primary
    @Bean(name = "db1EntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean
    entityManagerFactory(EntityManagerFactoryBuilder builder,
                         @Qualifier("db1DataSource") DataSource dataSource) {
        return builder
                .dataSource(dataSource)
                .packages("com.example.test.domain")
                .persistenceUnit("db1")
                .build();
    }

    @Primary
    @Bean(name = "db1TransactionManager")
    public PlatformTransactionManager transactionManager(
            @Qualifier("db1EntityManagerFactory") EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }
}

@EnableJpaRepositories 내 basePackages에 이 Config가 적용될 패키지 레벨을 설정한다.
그 후 각각 EntityManagerFactory와 TransactionManager 설정을 Bean으로 주입해준 뒤, @EnableJpaRepositories 어노테이션 내에 매핑해준다.

@Primaery 여러 Datasource 중 우선으로 사용할 Config에 붙여준다.
@Qualifier 여러 Datasource가 Bean으로 주입될 때 충돌되지 않도록 별칭으로 지정해준다.

그렇기 때문에 특정 데이터베이스의 config 파일에 @Primaery 어노테이션을 붙여서 Bean을 생성해주고, 그 외에 데이터베이스 설정 파일에는 @Qualifier 어노테이션 같은 걸로 지칭을 해줘야 한다.

Db2Config, Db3Config도 마찬가지로 구성하면 된다. 단, @Primary 어노테이션은 반드시 주 DB 구성에만 포함시켜야 한다. 그렇지 않을 경우 충돌이 발생해서 아래와 같은 오류가 발생한다.

Parameter 0 of method entityManagerFactory in com.example.test.global.config.Db1Config required a bean of type 'org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder' that could not be found.

profile
모든 것을 기록하는 벨로그 💻

0개의 댓글