▼ Backend/스프링 (Spring)

Spring Boot | JPA, 다중 데이터베이스 구성하기

Valar 2022. 5. 25. 16:31
반응형

구성환경

Spring Boot 2.7.0, MariaDB 10.5.13

 

기존에 하나의 데이터 소스를 통해 정상 작동하는 프로젝트에서 2개 이상의 데이터 소스를 사용하기 위해 작성된 내용입니다. 기본 스프링 부트 데이터베이스 연동은 데이터베이스(MariaDB) 연동 및 JPA CRUD을 참고해주세요.

application.yml

2개의 datasource를 설정합니다. (2개 이상 필요시 이름을 다르게 해서 추가) 

 

spring:
  datasource:
    driverClassName: org.mariadb.jdbc.Driver
    jdbcUrl: jdbc:mariadb://localhost:3306/first_database
    username: admin
    password: password!@#
    
  second-datasource:
    driverClassName: org.mariadb.jdbc.Driver
    jdbcUrl: jdbc:mariadb://localhost:3306/second_database
    username: admin
    password: password!@#

기본 스프링 부트 datasource 설정과는 다른 점이 url로 되어있던 부분을 jdbcUrl로 변경해야 합니다. JavaConfig를 통해 사용자가 직접 지정하여 데이터 소스를 구성할 경우 HikariCP가 url이 아닌 jdbcUrl을 사용하기 때문입니다.

*Spring Boot DataSource Reference

https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#data.sql.datasource.embedded

📌 사용자 지정 데이터 소스 구성

FirstDatasourceConfig.java

1. @EnableJpaRepositories (
    basePackages = "com.demo.domain.first",
)
  적용할 repository의 패키지 경로를 작성한다.

2. em.setPackagesToScan(new String[] {"com.demo.domain.first"});
 적용 할 entity의 패키지 경로를 작성한다.

 

@EnableJpaRepositories(
    basePackages = "com.demo.domain.first",
    entityManagerFactoryRef = "firstEntityManager",
    transactionManagerRef = "firstTransactionManager"
)
@Configuration
public class FirstDatasourceConfig {
    @Primary
    @Bean
    public LocalContainerEntityManagerFactoryBean firstEntityManager() {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(firstDataSource());
        em.setPackagesToScan(new String[] {"com.demo.domain.first"});
        em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
        return em;
    }

    @Primary
    @Bean
    @ConfigurationProperties(prefix="spring.datasource")
    public DataSource firstDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Primary
    @Bean
    public PlatformTransactionManager firstTransactionManager() {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(firstEntityManager().getObject());
        return transactionManager;
    }
}

 

SecondDatasourceConfig.java

1. @EnableJpaRepositories (
    basePackages = "com.demo.domain.second",
)
  적용할 repository의 패키지 경로를 작성한다.

2. em.setPackagesToScan(new String[] {"com.demo.domain.second"});
 적용 할 entity의 패키지 경로를 작성한다.

 

@EnableJpaRepositories(
    basePackages = "com.demo.domain.second",
    entityManagerFactoryRef = "secondEntityManager",
    transactionManagerRef = "secondTransactionManager"
)
@Configuration
public class SecondDatasourceConfig {
    @Bean
    public LocalContainerEntityManagerFactoryBean secondEntityManager() {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(secondDataSource());
        em.setPackagesToScan(new String[] {"com.demo.domain.second"});
        em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
        return em;
    }

    @Bean
    @ConfigurationProperties(prefix="spring.second-datasource")
    public DataSource secondDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    public PlatformTransactionManager secondTransactionManager() {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(secondEntityManager().getObject());
        return transactionManager;
    }
}

 

 


코드 설명

@EnableJpaRepositories

  • JPA Repository Bean을 활성화하는 어노테이션
  • basePackages 속성을 주지 않으면 @SpringBootApplication에 설정한 Bean scan 범위로 지정
  • entityManagerFactoryRef, transactionManagerRef 명시

@Configuration

  • 빈 설정을 담당하는 클래스가 지정
  • 이 클래스 안에서 @Bean메서드를 선언하면, 그 메서드를 통해 스프링 빈을 정의하고 생명주기를 설정

@Primary

  • 스프링은 하나의 타입에 빈 객체가 여러 개인 경우 그중 우선순위를 갖는 빈이라는 것을 지정할 수 있도록 @Primary 어노테이션을 제공

@Bean

  • @Configuration 선언한 빈 설정 클래스에 빈 선언을 담당하는 어노테이션으로, 메서드에만 지정할 수 있다.

LocalContainerEntityManagerFactoryBean

  • SessionFactoryBean과 동일하게 DataSource와 Hibernate Property, Entity가 위치한 package를 지정
  • Hibernate 기반으로 동작을 지정하는 JpaVendor를 설정
  • Hibernate vendor과 JPA 간의 Adapter를 설정

@ConfigurationProperties

  • *. properties , *. yml 파일에 있는 property를 자바 클래스에 값을 가져와서(바인딩) 사용할 수 있게 해주는 어노테이션

DataSource

  • 사용자 지정 데이터 소스를 사용하기 위해 정의

PlatformTransactionManager

  • @Transactional이 포함된 메서드가 호출될 경우, PlatformTransactionManager를 사용하여 트랜잭션을 시작하고, 정상 여부에 따라 Commit 또는 Rollback 한다.

 

Download

FirstDatasourceConfig.java
0.00MB
SecondDatasourceConfig.java
0.00MB

 

반응형