Notice
Recent Posts
Recent Comments
Link
반응형
이로
SPRING JPA 다중DB 접속 본문
반응형
1.요구사항
- 한 서버가 두 개 이상의 DB와 연결되어 있어야 한다. (필자는 MySQL, PostgreSQL 두 대 연결하였다.)
- Spring JPA를 사용한다.
2. 의존성
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
(버전이 없는 이유는 Parent 에서 Spring 의 버전에 따라 두 의존성을 관리해 주기 때문이다.)
간략 용어 설명
JPA : JAVA Persistence API 의 줄임말로, 관계형 데이터베이스 관리를 표현하는 자바 API 이다.
Hibernate : 자바를 위한 오픈소스 ORM 프레임워크를 제공한다.
ORM : "관계형 데이터베이서의 구조화된 데이터와 자바와 같은 객체 지향 언어간의 구조적 불이리를 어떻게 해소할 수 있을까?" 라는 질문에서 나온 객체-관계 매핑 프레임워크이다.
Data JPA : JPA 기반의 Repository를 쉽게 구현할 수 있도록 Spring Data에서 제공한다.
Spring Data Jdbc 는 Spring Jdbc와 Spring Data Jpa 사이의 빈 공간 채우기 위해 작성되었다. 자세한 설명은 아래 참고링크 참조
3. 구성
기본 원리는 Configuration 으로 각 DB에 접속할 때 사용할 정보를 각 각 설정해서 저장해 두면 된다. 메인으로 사용될 DB에는 Primary설정을 해주면 된다. 먼저 코드를 보면 다음과 같다.
Master DB
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "mysqlEntityManager", transactionManagerRef = "mysqlTransactionManager", basePackages = "적용할.repository")
public class MasterDBConfig {
@Autowired
private Environment env;
@Primary
@Bean
public DataSource mysqlDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty("spring.main.datasource.driverClassName"));
dataSource.setUrl(env.getProperty("spring.main.datasource.url"));
dataSource.setUsername(env.getProperty("spring.main.datasource.username"));
dataSource.setPassword(env.getProperty("spring.main.datasource.password"));
return dataSource;
}
@Primary
@Bean
public LocalContainerEntityManagerFactoryBean mysqlEntityManager() {
LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
HashMap<String, Object> properties = new HashMap<>();
localContainerEntityManagerFactoryBean.setDataSource(mysqlDataSource());
localContainerEntityManagerFactoryBean.setPackagesToScan(new String[] { "적용할.엔티티.패키지.entity" });
localContainerEntityManagerFactoryBean.setJpaVendorAdapter(vendorAdapter);
properties.put("hibernate.hbm2ddl.auto", env.getProperty("spring.main.hibernate.hbm2ddl.auto"));
properties.put("hibernate.dialect", env.getProperty("spring.main.hibernate.dialect"));
localContainerEntityManagerFactoryBean.setJpaPropertyMap(properties);
return localContainerEntityManagerFactoryBean;
}
@Primary
@Bean
public PlatformTransactionManager mysqlTransactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(mysqlEntityManager().getObject());
return transactionManager;
}
}
Sub DB
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "subEntityManager", transactionManagerRef = "subTransactionManager", basePackages = "적용할.repository")
public class DataDBConfig {
@Autowired
private Environment env;
@Bean
public DataSource subDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty("spring.sub.datasource.driverClassName"));
dataSource.setUrl(env.getProperty("spring.sub.datasource.url"));
dataSource.setUsername(env.getProperty("spring.sub.datasource.username"));
dataSource.setPassword(env.getProperty("spring.sub.datasource.password"));
return dataSource;
}
@Bean
public LocalContainerEntityManagerFactoryBean subEntityManager() {
LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
HashMap<String, Object> properties = new HashMap<>();
localContainerEntityManagerFactoryBean.setDataSource(subDataSource());
localContainerEntityManagerFactoryBean.setPackagesToScan("적용할.entity");
localContainerEntityManagerFactoryBean.setJpaVendorAdapter(vendorAdapter);
properties.put("hibernate.hbm2ddl.auto", env.getProperty("spring.sub.hibernate.hbm2ddl.auto"));
properties.put("hibernate.dialect", env.getProperty("spring.sub.hibernate.dialect"));
localContainerEntityManagerFactoryBean.setJpaPropertyMap(properties);
return localContainerEntityManagerFactoryBean;
}
@Bean
public PlatformTransactionManager subTransactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(subEntityManager().getObject());
return transactionManager;
}
}
application.properties
## MySQL
#spring.datasource.type=org.apache.tomcat.jdbc.pool.DataSource
spring.main.datasource.url=MySql접속주소
spring.main.datasource.username=MySql접속아이디
spring.main.datasource.password=MySql접속비밀번호
spring.main.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.main.hibernate.hbm2ddl.auto=none
spring.main.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
## PostGreSQL
spring.sub.datasource.url=PostgreSQL접속주소
spring.sub.datasource.username=PostgreSQL접속아이디
spring.sub.datasource.password=PostgreSQL접속비밀번호
spring.sub.datasource.driverClassName=org.postgresql.Driver
spring.sub.hibernate.hbm2ddl.auto=none
spring.sub.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
기본적으로 application.properties 에서 설정값을 저장해주고, 그 저장한 값을 각 DB Config 파일의 해당 값에 삽입해주면 된다.
정리
- 사용할 각 DB 의 DataSource를 생성
- 각 각의 EntityManager, TransactionManager를 EntityManagerFactory로 만든다
- @EnableJpaRepositories(entityManagerFactoryRef = "", transactionManagerRef = "", basePackages = "") 설정한다.
(entityManagerFactoryRef 는 Entity 위치, basePackages 는 연결할 repository 위치)
참고
반응형
'컴퓨터 > 사용했던 기술 정리' 카테고리의 다른 글
HIGHCHART (0) | 2020.12.14 |
---|---|
Httpd Proxy 설정 (하나의 IP 여러 도메인 연결) (0) | 2020.11.24 |
Comments