Spring Boot

QueryDSL 다중 DB 설정하기

수수한개발자 2023. 6. 27.
728x90

개발 환경

Java 17

spring boot 3.1.1

h2database

 

PrimaryDatasource

@Configuration
@EnableJpaRepositories(
        entityManagerFactoryRef = "primaryEntityManager",
        transactionManagerRef = "primaryTransactionManager",
        basePackages = "com.example.multiplebeans.repository.primary"
)
public class PrimaryDatasource {

    @Bean
    @ConfigurationProperties("spring.datasource.hikari.primary") // 외부 설정을 주입 받는 객체라는 뜻이다.
    public DataSource primaryDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    public PlatformTransactionManager primaryTransactionManager() {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(primaryEntityManager().getObject());

        return transactionManager;
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean primaryEntityManager() {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(primaryDataSource());

        // Entity 패키지 경로
        em.setPackagesToScan("com.example.multiplebeans.entity.primary");

        HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(adapter);

        // Hibernate 설정
        Properties properties = new Properties();
        properties.put("hibernate.show_sql" , "true");
        properties.put("hibernate.format_sql" , "true");
        em.setJpaProperties(properties);
        em.setPersistenceUnitName("primaryEntityManager");

        return em;
    }
}

 

SecondDatasource

@Configuration
@EnableJpaRepositories(
        entityManagerFactoryRef = "secondEntityManager",
        transactionManagerRef = "secondTransactionManager",
        basePackages = "com.example.multiplebeans.repository.second"
)
public class SecondDatasource {

    @Bean
    @ConfigurationProperties("spring.datasource.hikari.second") // 외부 설정을 주입 받는 객체라는 뜻이다.
    public DataSource secondDataSource() {
        return DataSourceBuilder.create().build();
    }

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

        return transactionManager;
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean secondEntityManager() {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(secondDataSource());

        // Entity 패키지 경로
        em.setPackagesToScan("com.example.multiplebeans.entity.second");

        HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(adapter);

        // Hibernate 설정
        Properties properties = new Properties();
        properties.put("hibernate.show_sql" , "true");
        properties.put("hibernate.format_sql" , "true");
        properties.put("hibernate.hbm2ddl.auto", "create");
        em.setJpaProperties(properties);
		em.setPersistenceUnitName("secondEntityManager");

        return em;
    }
}

 

코드 설명

@EnableJpaRepositories

- JPA Repository Bean을 활성해주는 어노테이션

- basePackages 속성을 주지 않으면 @SpringBootApplication 설정한 Bean scan 범위로 지정

- entityManagerFactoryRef, transactionManagerRef 명시

 

 

LocalContainerEntityManagerFactoryBean

- SessionFactoryBean 동일하게 DataSource Hibernate Property, Entity 위치한 package 지정

- Hibernate 기반으로 동작을 지정하는 JpaVendor 설정

- Hibernate vendor JPA 간의 Adapter 설정

 

@ConfigurationProperties

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

 

 

PlatformTransctionManager

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

 

 

PrimaryQueryDslConfig

@Configuration
public class PrimaryQueryDslConfig {

    @PersistenceContext(unitName = "primaryEntityManager")
    private EntityManager em;

    @Bean
    public JPAQueryFactory primaryJpaQueryFactory() {
        return new JPAQueryFactory(em);
    }
}

 

 

SecondQueryDslConfig

@Configuration
public class SecondQueryDslConfig {

    @PersistenceContext(unitName = "secondEntityManager")
    private EntityManager em;

    @Bean
    public JPAQueryFactory secondJpaQueryFactory() {
        return new JPAQueryFactory(em);
    }
}

 

JpaRepositoryCustom

 

@Service
@RequiredArgsConstructor
public class JpaRepositoryCustom {
    
    private final JPAQueryFactory primaryJpaQueryFactory;
}

 

기본적으로 스프링 빈은 @Bean 등록시 메서드 이름으로 등록 된다. 그래서 주입시 이 메서드 명과 동일하게 작성하면 주입 받을 수 있다.

728x90

댓글