본문 바로가기
  • 실행력이 모든걸 결정한다
Spring Series/Spring Boot

[Spring Boot] 2개의 DB를 사용하는 방법

by 김코더 김주역 2022. 11. 12.
반응형

SpringBoot 애플리케이션에서 1개의 DB만 사용하는 경우에는 @EnableJpaRepositories를 작성하지 않아도 JpaRepository에 대한 기본적인 설정이 이루어진다.

그러나 2개의 DB를 사용하는 경우에는 2개의 DB 설정 파일을 만들어서 각각 @EnableJpaRepositories에 JpaRepository에 연결할 EntityManagerFactory, TransactionManager를 지정해줘야 한다.

 

 

Test, User 2개의 DB를 사용한다고 해보자.

필자는 이에 대해서 각각 TestDBConfig.java, UserDBConfig.java 설정 클래스를 만들었다.

 

<TestDBConfig.java>

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = {"com.example.demo.jpa.repository.sampledata"}, // JpaRepository들이 위치한 패키지
        entityManagerFactoryRef = "entityManagerFactory", // 연결할 엔티티 매니저 팩토리
        transactionManagerRef = "transactionManager") // 연결할 트랜잭션 매니저
public class TestDBConfig {

    @Bean
    @Primary
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
        emf.setDataSource(dataSource());
        emf.setPackagesToScan(new String[] {"com.example.demo.entity.sampledata"});
        emf.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
        emf.setJpaProperties(jpaProperties());
        return emf;
    }

    Properties jpaProperties(){
        Properties properties = new Properties();
        properties.setProperty("hibernate.hbm2ddl.auto", "create-drop");
        properties.setProperty("hibernate.dialect","org.hibernate.dialect.MySQL5InnoDBDialect");
        properties.setProperty("hibernate.show_sql","true");
        properties.setProperty("hibernate.format_sql","true");
        properties.setProperty("hibernate.id.new_generator_mappings","true");
        properties.setProperty("hibernate.physical_naming_strategy","org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy");
        return properties;
    }

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

    @Bean
    @Primary
    public PlatformTransactionManager transactionManager() {
        JpaTransactionManager jpaTransactionManager = new JpaTransactionManager(entityManagerFactory().getObject());
        return jpaTransactionManager;
    }
}

- Test가 메인 DB이기 때문에 EntityManagerFactory, DataSource, TransactionManager에 @Primary를 붙여주었다.

※ @Primary의 역할 : @Autowired는 bean을 주입 받을 때 1순위로 Bean의 타입을 보고, 해당 Bean의 타입이 2개 이상이라면 2순위로 Bean의 이름을 본다. Bean에 @Primary를 붙이면 Bean의 타입을 볼 때 중복되는 타입이 있다면 2순위로 넘어가지 않고 @Primary가 붙은 Bean을 반환하게 된다.

 

<UserDBConfig.java>

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = {"com.example.demo.jpa.repository.user"},
        entityManagerFactoryRef = "userEntityManagerFactory",
        transactionManagerRef = "userTransactionManager")
public class UserDBConfig {

    @Bean
    public LocalContainerEntityManagerFactoryBean userEntityManagerFactory() {
        LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
        emf.setDataSource(userDataSource());
        emf.setPackagesToScan(new String[]{"com.example.demo.entity.user"});
        emf.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
        emf.setJpaProperties(jpaProperties());
        return emf;
    }

    Properties jpaProperties() {
        Properties properties = new Properties();
        properties.setProperty("hibernate.hbm2ddl.auto", "create-drop");
        properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect");
        properties.setProperty("hibernate.show_sql", "true");
        properties.setProperty("hibernate.format_sql", "true");
        properties.setProperty("hibernate.id.new_generator_mappings", "true");
        properties.setProperty("hibernate.physical_naming_strategy", "org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy");
        return properties;
    }

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

    @Bean
    public PlatformTransactionManager userTransactionManager() {
        JpaTransactionManager jpaTransactionManager = new JpaTransactionManager(userEntityManagerFactory().getObject());
        return jpaTransactionManager;
    }
}

- 메인 DB가 아니라면 @Primary를 붙이지 않도록 주의하자.

 

반응형

댓글