Today
-
Yesterday
-
Total
-

ABOUT ME

-

  • Spring Boot | JPA, 다중 데이터베이스 구성하기
    ▼ Backend/스프링 (Spring) 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

     

    반응형

    댓글

Designed by Tistory.