1. 개요

Spring Boot 애플리케이션의 일반적인 시나리오는 단일 관계형 데이터베이스에 데이터를 저장하는 것입니다. 그러나 때때로 여러 데이터베이스에 액세스해야 합니다.

이 사용방법(예제)에서는 Spring Boot로 여러 데이터 소스를 구성하고 사용하는 방법을 배웁니다.

단일 데이터 소스를 처리하는 방법을 알아보려면 Spring Data JPA 소개를 확인하세요 .

2. 기본 동작

Spring Boot에서 데이터 소스를 선언하는 것이 application.yml 에서 어떻게 보이는지 기억해 봅시다 .

spring:
  datasource:
    url: ...
    username: ...
    password: ...
    driverClassname: ...

내부적으로 Spring은 이러한 설정을 org.springframework.boot.autoconfigure.jdbc.DataSourceProperties 의 인스턴스에 매핑합니다 .

구현을 살펴보겠습니다.

@ConfigurationProperties(prefix = "spring.datasource")
public class DataSourceProperties implements BeanClassLoaderAware, InitializingBean {

    // ...

    /**
     * Fully qualified name of the JDBC driver. Auto-detected based on the URL by default.
     */
    private String driverClassName;

    /**
     * JDBC URL of the database.
     */
    private String url;

    /**
     * Login username of the database.
     */
    private String username;

    /**
     * Login password of the database.
     */
    private String password;

    // ...

}

구성 속성을 Java 개체에 자동으로 매핑하는 @ConfigurationProperties 어노테이션을 지적해야 합니다 .

3. 기본값 확장

따라서 여러 데이터 소스를 사용하려면 Spring의 애플리케이션 컨텍스트 내에서 매핑이 다른 여러 빈을 선언해야 합니다.

구성 클래스를 사용하여 이 작업을 수행할 수 있습니다.

@Configuration
public class TodoDatasourceConfiguration {

    @Bean
    @ConfigurationProperties("spring.datasource.todos")
    public DataSourceProperties todosDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean
    @ConfigurationProperties("spring.datasource.topics")
    public DataSourceProperties topicsDataSourceProperties() {
        return new DataSourceProperties();
    }

}

데이터 소스의 구성은 다음과 같아야 합니다.

spring:
  datasource:
    todos:
      url: ...
      username: ...
      password: ...
      driverClassName: ...
    topics:
      url: ...
      username: ...
      password: ...
      driverClassName: ...

그런 다음 DataSourceProperties 개체 를 사용하여 데이터 소스를 만들 수 있습니다 .

@Bean
public DataSource todosDataSource() {
    return todosDataSourceProperties()
      .initializeDataSourceBuilder()
      .build();
}

@Bean
public DataSource topicsDataSource() {
    return topicsDataSourceProperties()
      .initializeDataSourceBuilder()
      .build();
}

4. 스프링 데이터 JDBC

Spring Data JDBC를 사용할 때 우리는 또한 DataSource 에 대해 하나의 JdbcTemplate 인스턴스를 설정해야 합니다 .

@Bean
public JdbcTemplate todosJdbcTemplate(@Qualifier("todosDataSource") DataSource dataSource) {
    return new JdbcTemplate(dataSource);
}

@Bean
public JdbcTemplate topicsJdbcTemplate(@Qualifier("topicsDataSource") DataSource dataSource) {
    return new JdbcTemplate(dataSource);
}

그런 다음 @Qualifier 를 지정하여 사용할 수도 있습니다 .

@Autowired
@Qualifier("topicsJdbcTemplate")
JdbcTemplate jdbcTemplate;

5. 스프링 데이터 JPA

Spring Data JPA를 사용할 때 다음과 같은 리포지토리를 사용하려고 합니다. 여기서 Todo 는 엔터티입니다.

public interface TodoRepository extends JpaRepository<Todo, Long> {}

따라서 각 데이터 소스에 대해 EntityManager 팩토리를 선언해야 합니다.

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
  basePackageClasses = Todo.class,
  entityManagerFactoryRef = "todosEntityManagerFactory",
  transactionManagerRef = "todosTransactionManager"
)
public class TodoJpaConfiguration {

    @Bean
    public LocalContainerEntityManagerFactoryBean todosEntityManagerFactory(
      Qualifier("todosDataSource") DataSource dataSource,
      EntityManagerFactoryBuilder builder) {
        return builder
          .dataSource(todosDataSource())
          .packages(Todo.class)
          .build();
    }

    @Bean
    public PlatformTransactionManager todosTransactionManager(
      @Qualifier("todosEntityManagerFactory") LocalContainerEntityManagerFactoryBean todosEntityManagerFactory) {
        return new JpaTransactionManager(Objects.requireNonNull(todosEntityManagerFactory.getObject()));
    }

}

알아두어야 할 몇 가지 제한 사항을 살펴보겠습니다.

각 데이터 소스에 대해 하나의 @EnableJpaRepositories 를 허용하도록 패키지를 분할해야 합니다 .

불행히도 EntityManagerFactoryBuilder 를 주입하려면 데이터 소스 중 하나를 @Primary 로 선언해야 합니다 .

이는 EntityManagerFactoryBuilder 가 org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration 에 선언되어 있고 이 클래스에는 단일 데이터 소스가 주입되어야 하기 때문입니다. 일반적으로 프레임워크의 일부는 구성된 여러 데이터 소스를 예상하지 못할 수 있습니다.

6. Hikari 연결 풀 구성

Hikari 를 구성 하려면 데이터 소스 정의 에 @ConfigurationProperties 를 추가하기만 하면 됩니다.

@Bean
@ConfigurationProperties("spring.datasource.todos.hikari")
public DataSource todosDataSource() {
    return todosDataSourceProperties()
      .initializeDataSourceBuilder()
      .build();
}

그런 다음 application.properties 파일 에 다음 줄을 삽입할 수 있습니다 .

spring.datasource.todos.hikari.connectionTimeout=30000 
spring.datasource.todos.hikari.idleTimeout=600000 
spring.datasource.todos.hikari.maxLifetime=1800000 

7. 결론

이 기사에서는 Spring Boot를 사용하여 여러 데이터 소스를 구성하는 방법을 배웠습니다.

일부 구성이 필요하고 표준에서 벗어날 때 함정이 있을 수 있지만 결국에는 가능하다는 것을 알았습니다.

항상 그렇듯이 모든 코드는  GitHub에서 사용할 수 있습니다 .

Persistence footer banner