[Spring JPA] Multiple Databases 다중 DB 연결하기
- Spring Data JPA
- Spring Boot
application.yml
spring:
datasource:
hikari:
bootdb1:
driver-class-name: [driver-name]
jdbc-url: [url]
username: [username]
password: [password]
bootdb2:
driver-class-name: [driver-name]
jdbc-url: [url]
username: [username]
password: [password]
* 정의해야 하는 것
- DataSource
- EntityManagerFactory
- TransactionManager
=> DBConfig를 만들어주자.
LegacyDBConfig.java
package com.jiyoon.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy;
import org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "legacyEntityManager",
transactionManagerRef = "legacyTransactionManager",
basePackages = "com.jiyoon.repository.legacy"
)
public class LegacyDBConfig {
@Bean
@ConfigurationProperties("spring.datasource.hikari.bootdb2")
public DataSource legacyDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
public PlatformTransactionManager legacyTransactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(legacyEntityManager().getObject());
return transactionManager;
}
@Bean
public LocalContainerEntityManagerFactoryBean legacyEntityManager() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(legacyDataSource());
em.setPackagesToScan("com.jiyoon.model.legacy");
HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(adapter);
Map<String, Object> properties = new HashMap<>();
properties.put("hibernate.physical_naming_strategy", SpringPhysicalNamingStrategy.class.getName());
properties.put("hibernate.implicit_naming_strategy", SpringImplicitNamingStrategy.class.getName());
em.setJpaPropertyMap(properties);
return em;
}
}
TargetDBConfig.java
package com.jiyoon.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy;
import org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "targetEntityManager",
transactionManagerRef = "targetTransactionManager",
basePackages = "com.jiyoon.repository.target"
)
public class TargetDBConfig {
@Bean
@Primary
@ConfigurationProperties("spring.datasource.hikari.bootdb1")
public DataSource targetDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@Primary
public PlatformTransactionManager targetTransactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(targetEntityManager().getObject());
return transactionManager;
}
@Bean
@Primary
public LocalContainerEntityManagerFactoryBean targetEntityManager() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(targetDataSource());
em.setPackagesToScan("com.jiyoon.model.target");
HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(adapter);
Map<String, Object> properties = new HashMap<>();
properties.put("hibernate.physical_naming_strategy", SpringPhysicalNamingStrategy.class.getName());
properties.put("hibernate.implicit_naming_strategy", SpringImplicitNamingStrategy.class.getName());
em.setJpaPropertyMap(properties);
return em;
}
}
@ConfigurationProperties 과 관련 글
https://frogand.tistory.com/131
* 트랜잭션
여러 단계를 수행할 때, 하나라도 실패하면 모두 취소되어야 하며 데이터의 무결성을 보장한다.
* 스프링의 트랜잭션 지원
선언적 트랜잭션을 지원한다. 트랜잭션의 범위를 코드 수준으로 정의 가능하며 설정 파일 또는 어노테이션을 이용하여 규칙 및 범위를 설정할 수 있다.
- PlatformTransactionManager
트랜잭션은 PlatformTransactionManager 인터페이스를 이용해 추상화했다. DB 연동 기술에 따라 각각의 구현 클래스가 제공된다.
실제 트랜잭션을 처리할 때 PlatformTransactionManager를 사용하진 않는다. 선언적 트랜잭션 방식으로 처리한다.
- JDBC 기반의 트랜잭션 설정
JDBC, MyBatis 등의 JDBC를 이용하는 경우 DataSourceTransactionManager를 관리자로 등록한다.
dataSource 프로퍼티를 통해 전달받은 Connection으로 commit, rollback을 수행하면서 관리한다.
- JPA 트랜잭션 설정
JPA를 사용하는 경우 JpaTransactionManager를 사용한다.
엔티티
package com.jiyoon.model.legacy
@Entity
@Table(schema = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
}
JPA 레포지토리
package com.jiyoon.repository.legacy;
public interface UserRepository extends JpaRepository<User, Integer> {}
출처
https://www.baeldung.com/spring-data-jpa-multiple-databases
'web > Spring' 카테고리의 다른 글
[Spring] 설정 값 분리의 필요성과 @Value의 사용법 및 동작 과정 (0) | 2022.03.14 |
---|---|
[Spring Boot] hibernate.hbm2ddl.auto 속성 정리 (0) | 2022.03.10 |
[Spring Boot] @ConfigurationProperties 사용법 (0) | 2022.03.07 |
[Spring MVC] Thymeleaf 반복문 처리, 상태변수 접근 (index) (0) | 2022.03.01 |
[Spring] Apache POI 를 이용한 엑셀 파일 읽기 (0) | 2022.02.28 |
댓글 개