spring batch : seperate database(batch, demo)

This commit is contained in:
haerong22
2021-05-11 16:11:56 +09:00
parent 0eb3f353cf
commit ab179884f8
7 changed files with 207 additions and 12 deletions

View File

@@ -3,8 +3,7 @@ package com.example.springbatch.application.job;
import com.example.springbatch.application.job.param.CreateArticleJobParam;
import com.example.springbatch.application.model.ArticleModel;
import com.example.springbatch.domain.entity.Article;
import com.example.springbatch.repository.ArticleRepository;
import lombok.RequiredArgsConstructor;
import com.example.springbatch.domain.repository.ArticleRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
@@ -17,32 +16,53 @@ import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.data.RepositoryItemWriter;
import org.springframework.batch.item.data.builder.RepositoryItemWriterBuilder;
import org.springframework.batch.item.database.builder.JdbcBatchItemWriterBuilder;
import org.springframework.batch.item.database.builder.JpaItemWriterBuilder;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.builder.FlatFileItemReaderBuilder;
import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.time.LocalDateTime;
import java.util.List;
@Configuration
@Slf4j
@RequiredArgsConstructor
public class CreateArticleJobConfig {
private final JobBuilderFactory jobBuilderFactory;
private final StepBuilderFactory stepBuilderFactory;
private final ArticleRepository articleRepository;
private final CreateArticleJobParam createArticleJobParam;
private final JdbcTemplate jdbcTemplate;
private final JdbcTemplate demoJdbcTemplate;
private final EntityManagerFactory demoEntityManagerFactory;
private final DataSource demoDataSource;
public CreateArticleJobConfig(JobBuilderFactory jobBuilderFactory,
StepBuilderFactory stepBuilderFactory,
ArticleRepository articleRepository,
CreateArticleJobParam createArticleJobParam,
@Qualifier("demoJdbcTemplate") JdbcTemplate demoJdbcTemplate,
@Qualifier("demoEntityManagerFactory") EntityManagerFactory demoEntityManagerFactory,
DataSource demoDataSource) {
this.jobBuilderFactory = jobBuilderFactory;
this.stepBuilderFactory = stepBuilderFactory;
this.articleRepository = articleRepository;
this.createArticleJobParam = createArticleJobParam;
this.demoJdbcTemplate = demoJdbcTemplate;
this.demoEntityManagerFactory = demoEntityManagerFactory;
this.demoDataSource = demoDataSource;
}
@Bean
public Job createArticleJob() {
return jobBuilderFactory.get("createArticleJob")
// .incrementer(new RunIdIncrementer())
.incrementer(new RunIdIncrementer())
.start(createArticleStep())
.build();
}
@@ -85,7 +105,7 @@ public class CreateArticleJobConfig {
// JDBC
@Bean
public ItemWriter<Article> createArticleWriterJDBC() {
return articles -> jdbcTemplate.batchUpdate("insert into Article (title, content, createdAt) values (?, ?, ?)",
return articles -> demoJdbcTemplate.batchUpdate("insert into Article (title, content, createdAt) values (?, ?, ?)",
articles,
1000,
(ps, article) -> {
@@ -103,4 +123,21 @@ public class CreateArticleJobConfig {
.build();
}
// ======================
// // JDBC
// @Bean
// public ItemWriter<Article> writerJDBC() {
// return new JdbcBatchItemWriterBuilder<Article>()
// .dataSource(demoDataSource)
// .build();
// }
// JPA
@Bean
public ItemWriter<Article> writerJPA() {
return new JpaItemWriterBuilder<Article>()
.entityManagerFactory(this.demoEntityManagerFactory)
.build();
}
}

View File

@@ -1,4 +1,4 @@
package com.example.springbatch.repository;
package com.example.springbatch.domain.repository;
import com.example.springbatch.domain.entity.Article;
import org.springframework.data.jpa.repository.JpaRepository;

View File

@@ -0,0 +1,22 @@
package com.example.springbatch.infrastructure;
import org.springframework.batch.core.configuration.annotation.DefaultBatchConfigurer;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;
@Configuration
public class BatchDataManagerConfig extends DefaultBatchConfigurer {
private final PlatformTransactionManager batchTransactionManager;
public BatchDataManagerConfig(
@Qualifier("batchTransactionManager") PlatformTransactionManager batchTransactionManager) {
this.batchTransactionManager = batchTransactionManager;
}
@Override
public PlatformTransactionManager getTransactionManager() {
return this.batchTransactionManager;
}
}

View File

@@ -0,0 +1,30 @@
package com.example.springbatch.infrastructure;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.factory.annotation.Qualifier;
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.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;
@Configuration
public class BatchDataSourceConfig {
@Bean
@Primary
@ConfigurationProperties(prefix = "spring.datasource.hikari.batch")
public DataSource batchDataSource() {
return DataSourceBuilder.create().type(HikariDataSource.class).build();
}
@Bean
public PlatformTransactionManager batchTransactionManager (
@Qualifier("batchDataSource") DataSource batchDataSource) {
return new DataSourceTransactionManager(batchDataSource);
}
}

View File

@@ -0,0 +1,63 @@
package com.example.springbatch.infrastructure;
import org.hibernate.cfg.AvailableSettings;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.util.Properties;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
basePackages = {
"com.example.springbatch.domain.repository"
},
entityManagerFactoryRef = "demoEntityManagerFactory",
transactionManagerRef = "demoTransactionManager"
)
public class DemoDataManagerConfig {
private final DataSource dataSource;
public DemoDataManagerConfig(
@Qualifier("demoDataSource") DataSource dataSource) {
this.dataSource = dataSource;
}
@Bean
public LocalContainerEntityManagerFactoryBean demoEntityManagerFactory() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(true);
em.setDataSource(this.dataSource);
em.setPersistenceUnitName("demoEntityManager");
em.setPackagesToScan(
"com.example.springbatch.domain.entity"
);
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(demoJpaProperties());
em.afterPropertiesSet();
return em;
}
@Bean
public JdbcTemplate demoJdbcTemplate(@Qualifier("demoDataSource") DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
private Properties demoJpaProperties() {
Properties properties = new Properties();
properties.setProperty(AvailableSettings.HBM2DDL_AUTO, "update");
properties.setProperty(AvailableSettings.SHOW_SQL, "true");
properties.setProperty(AvailableSettings.ALLOW_UPDATE_OUTSIDE_TRANSACTION, "true");
return properties;
}
}

View File

@@ -0,0 +1,31 @@
package com.example.springbatch.infrastructure;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.factory.annotation.Qualifier;
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.orm.jpa.JpaTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
@Configuration
public class DemoDataSourceConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource.hikari.demo")
public DataSource demoDataSource() {
return DataSourceBuilder.create().type(HikariDataSource.class).build();
}
@Bean
public PlatformTransactionManager demoTransactionManager(
@Qualifier("demoEntityManagerFactory") EntityManagerFactory demoEntityManagerFactory) {
JpaTransactionManager demoTransactionManager = new JpaTransactionManager();
demoTransactionManager.setEntityManagerFactory(demoEntityManagerFactory);
return demoTransactionManager;
}
}

View File

@@ -1,13 +1,25 @@
spring:
datasource:
url: jdbc:mysql://localhost:3306/batch?rewriteBatchedStatements=true
username: batch
password: 1234
# 데이터베이스 분리 방법 (2)
hikari:
batch:
jdbc-url: jdbc:mysql://localhost:3306/batch
driver-class-name: com.mysql.cj.jdbc.Driver
username: batch
password: 1234
demo:
jdbc-url: jdbc:mysql://localhost:3306/demo?rewriteBatchedStatements=true
driver-class-name: com.mysql.cj.jdbc.Driver
username: batch
password: 1234
batch:
initialize-schema: always
job:
names: ${job.name:createArticleJob}
# # 데이터베이스 분리 방법 (1)
# schema: schema-mysql.sql
# table-prefix: batch.BATCH_
jpa:
generate-ddl: true
hibernate: