두리공장
[Spring batch] Step 7 - Multi DataSource 사용하기 본문
스프링 배치를 구성하다보면, 배치용 메타DB는 H2 인메모리DB를 사용하고,
데이터 소스는 다양하게 연결할 경우도 있다.
이제, 여러 데이터소스를 연결하는 방법을 살펴보자
application.yml 에 다양한 데이터 소스를 설정한다.
spring:
default:
jdbc:
driver-class-name: org.h2.Driver
url: jdbc:h2:mem:userdb
username: sa
password:
mariadb:
jdbc:
url: jdbc:mariadb://localhost:3306/test_db
username: {userid}
password: {password}
driver-class-name: org.mariadb.jdbc.Driver
postgres:
jdbc:
url: jdbc:postgresql://localhost:5432/user_db
username: {userid}
password: {password}
driver-class-name: org.postgresql.Driver
batch:
jdbc:
initialize-schema: always
job:
names: jobForExec
H2는 휘발성 DB(인메모리)로 사용하기로 해서 h2:mem 으로 설정해 보았다. 휘발성DB이기 때문에 프로세스 생성시 스키마가 자동으로 생성되도록 initalize-schema를 always로 설정한다.
데이터 소스Bean을 만든다.
@Configuration
public class DataSourceConfig {
@Value("${spring.default.jdbc.driver-class-name}")
private String defaultDriverClassName;
@Value("${spring.default.jdbc.url}")
private String defaultJdbcUrl;
@Value("${spring.default.jdbc.username}")
private String defaultJdbcUsername;
@Value("${spring.default.jdbc.password}")
private String defaultJdbcPassword;
@Value("${spring.mariadb.jdbc.driver-class-name}")
private String mariadbDriverClassName;
@Value("${spring.mariadb.jdbc.url}")
private String mariadbJdbcUrl;
@Value("${spring.mariadb.jdbc.username}")
private String mariadbJdbcUsername;
@Value("${spring.mariadb.jdbc.password}")
private String mariadbJdbcPassword;
@Value("${spring.postgres.jdbc.driver-class-name}")
private String postgresDriverClassName;
@Value("${spring.postgres.jdbc.url}")
private String postgresJdbcUrl;
@Value("${spring.postgres.jdbc.username}")
private String postgresJdbcUsername;
@Value("${spring.postgres.jdbc.password}")
private String postgresJdbcPassword;
@Primary
@Bean(name="defaultDataSource")
public DataSource defaultDataSource(){
return getDataSource(defaultDriverClassName,defaultJdbcUrl,defaultJdbcUsername,defaultJdbcPassword);
}
@Bean(name="mariadbDataSource")
public DataSource mariadbDataSource(){
return getDataSource(mariadbDriverClassName,mariadbJdbcUrl,mariadbJdbcUsername,mariadbJdbcPassword);
}
@Bean(name="postgresDataSource")
public DataSource postgresDataSource(){
return getDataSource(postgresDriverClassName,postgresJdbcUrl,postgresJdbcUsername,postgresJdbcPassword);
}
private DataSource getDataSource(String driverClassName, String url, String username, String password){
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(driverClassName);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
}
H2는 @Primary 어노테이션을 주어서 메타DB로 사용한다.
나머지 데이터 소스는 Bean에 name="" 을 주어서 alias을 설정해 두자.
Batch Job 에 DataSource를 연결하자
@EnableBatchProcessing
@SpringBootApplication
public class BatchApplication {
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Autowired @Qualifier("mariadbDataSource")
private DataSource mariadbDataSource;
// DB를 읽기위한 ItemReader 이다.
@Bean
@StepScope
public JdbcPagingItemReader<Ranking> rankingItemReader2(
DataSource dataSource
) throws Exception {
return new JdbcPagingItemReaderBuilder<Ranking>()
.name("rankingItemReader")
.dataSource(mariadbDataSource)
.queryProvider(pagingQueryProvider(mariadbDataSource))
.pageSize(10)
.rowMapper(new BeanPropertyRowMapper<>(Ranking.class))
.build();
}
@Bean
public PagingQueryProvider pagingQueryProvider(DataSource dataSource) throws Exception {
SqlPagingQueryProviderFactoryBean factoryBean = new SqlPagingQueryProviderFactoryBean();
factoryBean.setSelectClause("select *");
factoryBean.setFromClause("from spi_global_rankings");
//factoryBean.setWhereClause("where rank = :rank");
factoryBean.setSortKey("rank");
factoryBean.setDataSource(mariadbDataSource);
return factoryBean.getObject();
}
//스텝을 만든다.
@Bean
public Step stepForExec() throws Exception {
return this.stepBuilderFactory.get("stepForExec")
.<Ranking, Ranking>chunk(1)
.reader(rankingItemReader2(mariadbDataSource))
.writer(execItemWriter(null))
.build();
}
//잡을 만든다.
@Bean
public Job jobForExec() throws Exception {
return this.jobBuilderFactory.get("jobForExec")
.start(stepForExec())
.build();
}
public static void main(String[] args) {
SpringApplication.run(BatchApplication.class, args);
}
}
출력 결과
2022-05-24 22:49:53.235 INFO 7332 --- [ main] com.sunnier.batch.BatchApplication : Starting BatchApplication using Java 1.8.0_202 on DESKTOP-AHN11RT with PID 7332 (C:\git_repo\batch\target\classes started by sunni in C:\git_repo\batch)
2022-05-24 22:49:53.238 INFO 7332 --- [ main] com.sunnier.batch.BatchApplication : No active profile set, falling back to 1 default profile: "default"
2022-05-24 22:50:24.403 INFO 7332 --- [ main] o.s.b.c.r.s.JobRepositoryFactoryBean : No database type set, using meta data indicating: H2
2022-05-24 22:50:24.517 INFO 7332 --- [ main] o.s.b.c.l.support.SimpleJobLauncher : No TaskExecutor has been set, defaulting to synchronous executor.
2022-05-24 22:50:24.622 INFO 7332 --- [ main] com.sunnier.batch.BatchApplication : Started BatchApplication in 31.918 seconds (JVM running for 33.383)
2022-05-24 22:50:24.624 INFO 7332 --- [ main] o.s.b.a.b.JobLauncherApplicationRunner : Running default command line with: [argu=foo12]
2022-05-24 22:50:24.696 INFO 7332 --- [ main] o.s.b.c.l.support.SimpleJobLauncher : Job: [SimpleJob: [name=jobForExec]] launched with the following parameters: [{argu=foo12}]
2022-05-24 22:50:24.739 INFO 7332 --- [ main] o.s.batch.core.job.SimpleStepHandler : Executing step: [stepForExec]
H2가 메타DB로 만들어지고 배치가 실행된다.
'java' 카테고리의 다른 글
[Spring & jQuery] 파일 및 Json 데이터 업로드 (file & json data) (0) | 2022.05.30 |
---|---|
[Spring batch] Step 8 - 2개이상 write 작업수행을 위해 CompositeItemWriter를 사용하자 (데이터 출력을 위한 CustomItemWriter 작성 포함) (0) | 2022.05.26 |
[Spring batch] Step 6 - DB를 읽어서 서비스 Method 호출하기 (0) | 2022.05.22 |
[Spring batch] Step 5 - DB를 읽어서 DB에 저장하기 (0) | 2022.03.24 |
[Spring batch] Step 3 - CSV 파일을 읽어서 DB에 저장하기 (0) | 2022.03.21 |