티스토리 뷰
협업 업체에서 ERP 연동을 위한 DB 연동을 요청.
ERP 관리 업체에서 여러 업체가 있으니 API 통신 말고 각 업체들이 알아서 ERP DB에 붙어 데이터 입력 요청.
새로 1개의 어플리케이션을 띄우고 배치를 돌려 주기적으로 기존데이터를 ERP에 입력하기로 결정.
연결 테스팅해볼 DB는 MySQL과 ORACLE임.
Spring data JPA를 통해 연결까지 테스트 진행.
Maven dependency
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<version>21.8.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>2.7.8</version>
</dependency>
yml 작성
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://ip:port/db
username: id
password: pw
second-datasource:
driver-class-name: oracle.jdbc.driver.OracleDriver
jdbc-url: jdbc:oracle:thin:@ip:port/sid(:) or service name(/)
username: id
password: pw
메인 datasource와 서브 datasource를 나눠놔야 한다.
네이밍은 개개인마다 알아서 지정해주고 설정 파일 작성때 잘넣어주면 된다. (oracle은 접속시 맨끝에 sid는 prefix로 ':'를 서비스명은 '/'를 사용한다.)
Config class 작성
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
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 javax.sql.DataSource;
@EnableJpaRepositories(
basePackages = "JPA 파일 스캔 경로 ex) com.demo.mysql",
entityManagerFactoryRef = "mySqlEntityManager",
transactionManagerRef = "mySqlTransactionManager"
)
@Configuration
public class MySqlDataSourceConfig {
@Primary
@Bean
public LocalContainerEntityManagerFactoryBean mySqlEntityManager() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(mySqlDataSource());
em.setPackagesToScan(new String[] {"JPA 파일 스캔 경로 basePackages 지정과 같으 면 됨"});
em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
return em;
}
@Primary
@Bean
@ConfigurationProperties(prefix="spring.datasource")
public DataSource mySqlDataSource() {
return DataSourceBuilder.create().build();
}
@Primary
@Bean
public PlatformTransactionManager mySqlTransactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(mySqlEntityManager().getObject());
return transactionManager;
}
}
먼저 메인 datasource인 MySQL 설정 클래스를 작성해준다.
@Primary 애노테이션을 통해 MySQL이 메인 datasource임을 선언해준다.
basePackages는 JPA 도메인 파일을 찾을 베이스 경로를 설정해준다.
작성하지 않을 시에는 스프링 부트가 시작되는 @ComponentScan을 기준으로 서칭한다.
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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 javax.sql.DataSource;
@EnableJpaRepositories(
basePackages = "JPA domain base path",
entityManagerFactoryRef = "oracleEntityManager",
transactionManagerRef = "oracleTransactionManager"
)
@Configuration
public class OracleDataSourceConfig {
@Bean
public LocalContainerEntityManagerFactoryBean oracleEntityManager() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(oracleDataSource());
em.setPackagesToScan(new String[] {"JPA domain base path"});
em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
return em;
}
@Bean
@ConfigurationProperties(prefix = "spring.second-datasource")
public DataSource oracleDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
public PlatformTransactionManager oracleTransactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(oracleEntityManager().getObject());
return transactionManager;
}
}
테스트로 연결해볼 Domain을 각 디비별로 작성해준다.
나의 경우 실제 사용하는 item_ct(MySQL), MCHPRODEMP(Oracle)라는 테이블을 작성 한 후 연결 테스트를 해볼 것이다.
Test 작성
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.Transactional;
import java.util.Optional;
@SpringBootTest
@EnableTransactionManagement
class ErplinkApplicationTests {
@Autowired
ItemCtRepository itemCtRepository;
@Autowired
MchProdEmpRepository mchProdEmpRepository;
@Test
@Transactional("mySqlTransactionManager")
void 아이템씨티찾기테스트() {
Optional<ItemCt> ic = itemCtRepository.findById(505968);
Assertions.assertThat(ic.isPresent()).isTrue();
}
@Test
@Transactional("oracleTransactionManager")
void 오라클DB연결테스트() {
MchProdEmpId meId = new MchProdEmpId();
meId.setShpJpNO("P02301050009001");
meId.setEmpNo("198612001");
MchProdEmp me = mchProdEmpRepository.getReferenceById(meId);
System.out.println(me.getCrtDate());
Assertions.assertThat(me.getCrtDate()).isEqualTo("20230105");
}
}
이제 설정한 datasource들 중 사용할 datasource Transactional 애노테이션에 선언해주면 된다.
기존 설정 클래스에서 작성한 것 중 transactionManagerRef를 기준으로 작성해주면 된다.
MySQL 연결의 경우 PK를 Integer 한 칼럼으로 별 다른 이상 없이 정상적으로 불러져왔다.
(테이블 이름을 카멜로 못잡는 등의 잔버그는 있었지만 각 테이블 이름 모두 선언해주면서 해결.)
하지만 ORACLE은 PK가 복합키로 이루어져 있어 @Embedded 애노테이션을 통해 하나의 PK 클래스를 더 만들어 줬다.(MchProdEmpId)
JPARepository ID에 해당 MchProdEmpId를 선언하여 해당 Embedded ID 값으로 정상 조회를 할 수 있었다.
'Spring boot' 카테고리의 다른 글
12. Spring boot - batch, scheduler 기본 설정 (0) | 2023.02.07 |
---|---|
24. STS - 게시판 (다중 파일 업로드 & 다운로드 구현하기 03) (0) | 2021.05.11 |
23. STS - 게시판 (다중 파일 업로드 & 다운로드 구현하기 02) (0) | 2021.05.10 |
22. STS - 게시판 (다중 파일 업로드 & 다운로드 구현하기 01) (0) | 2021.05.09 |
21. STS - REST 방식으로 댓글 삭제 구현하기 (0) | 2021.05.09 |