Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 5c09968

Browse files
committed
Refactored spring batch example
1 parent c8d77a4 commit 5c09968

File tree

11 files changed

+199
-77
lines changed

11 files changed

+199
-77
lines changed

‎spring-batch-demo/src/main/java/com/stacktips/app/SpringBatchDemoApplication.java‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
@SpringBootApplication
77
public class SpringBatchDemoApplication {
88

9-
public static void main(String[] args) {
10-
SpringApplication.run(SpringBatchDemoApplication.class, args);
11-
}
9+
public static void main(String[] args) {
10+
SpringApplication.run(SpringBatchDemoApplication.class, args);
11+
}
1212

1313
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.stacktips.app.config;
2+
3+
import lombok.RequiredArgsConstructor;
4+
import org.springframework.batch.core.Job;
5+
import org.springframework.batch.core.JobExecutionException;
6+
import org.springframework.batch.core.JobParametersBuilder;
7+
import org.springframework.batch.core.launch.JobLauncher;
8+
import org.springframework.boot.context.event.ApplicationReadyEvent;
9+
import org.springframework.context.event.EventListener;
10+
import org.springframework.stereotype.Component;
11+
12+
@Component
13+
@RequiredArgsConstructor
14+
public class ApplicationEvent {
15+
16+
private final JobLauncher jobLauncher;
17+
private final Job csvImporterJob;
18+
19+
@EventListener(ApplicationReadyEvent.class)
20+
public void applicationEvent() throws JobExecutionException {
21+
jobLauncher.run(csvImporterJob, new JobParametersBuilder()
22+
.addString("ignoreCountry", "India")
23+
.toJobParameters());
24+
25+
}
26+
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package com.stacktips.app.config;
2+
3+
import com.stacktips.app.model.Customer;
4+
import com.stacktips.app.utils.DateUtils;
5+
import jakarta.persistence.EntityManagerFactory;
6+
import org.springframework.batch.core.*;
7+
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
8+
import org.springframework.batch.core.job.builder.JobBuilder;
9+
import org.springframework.batch.core.launch.support.RunIdIncrementer;
10+
import org.springframework.batch.core.repository.JobRepository;
11+
import org.springframework.batch.core.step.builder.StepBuilder;
12+
import org.springframework.batch.item.ItemReader;
13+
import org.springframework.batch.item.ItemWriter;
14+
import org.springframework.batch.item.database.JpaItemWriter;
15+
import org.springframework.batch.item.database.builder.JpaItemWriterBuilder;
16+
import org.springframework.batch.item.file.FlatFileItemReader;
17+
import org.springframework.batch.item.file.builder.FlatFileItemReaderBuilder;
18+
import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper;
19+
import org.springframework.context.annotation.Bean;
20+
import org.springframework.context.annotation.Configuration;
21+
import org.springframework.core.io.ClassPathResource;
22+
import org.springframework.transaction.PlatformTransactionManager;
23+
24+
@Configuration
25+
@EnableBatchProcessing
26+
public class BatchConfig {
27+
28+
@Bean
29+
public FlatFileItemReader<Customer> reader() {
30+
return new FlatFileItemReaderBuilder<Customer>()
31+
.linesToSkip(1)
32+
.name("csvItemReader")
33+
.resource(new ClassPathResource("customers.csv"))
34+
.delimited()
35+
.delimiter(",")
36+
.names("index", "customerId", "firstName", "lastName", "company",
37+
"city", "country", "phone1",
38+
"phone2", "email", "subscriptionDate", "website")
39+
.fieldSetMapper(fieldSet -> {
40+
return Customer.builder()
41+
.customerId(fieldSet.readString("customerId"))
42+
.firstName(fieldSet.readString("firstName"))
43+
.lastName(fieldSet.readString("lastName"))
44+
.company(fieldSet.readString("company"))
45+
.city(fieldSet.readString("city"))
46+
.country(fieldSet.readString("country"))
47+
.phone1(fieldSet.readString("phone1"))
48+
.phone2(fieldSet.readString("phone2"))
49+
.email(fieldSet.readString("email"))
50+
.website(fieldSet.readString("website"))
51+
.subscriptionDate(DateUtils.parseDate(fieldSet.readString("subscriptionDate")))
52+
.build();
53+
})
54+
.build();
55+
56+
}
57+
58+
59+
@Bean
60+
public JpaItemWriter<Customer> writer(EntityManagerFactory entityManagerFactory) {
61+
return new JpaItemWriterBuilder<Customer>()
62+
.entityManagerFactory(entityManagerFactory)
63+
.build();
64+
}
65+
66+
@Bean
67+
public Step csvImporterStep(ItemReader<Customer> reader, ItemWriter<Customer> writer,
68+
JobRepository jobRepository, PlatformTransactionManager transactionManager,
69+
CustomJobProcessor processor) {
70+
return new StepBuilder("csvImporterStep", jobRepository)
71+
.<Customer, Customer>chunk(50, transactionManager)
72+
.reader(reader)
73+
.processor(processor)
74+
.writer(writer)
75+
.allowStartIfComplete(true)
76+
.build();
77+
}
78+
79+
@Bean
80+
public Job csvImporterJob(Step csvImporterStep, JobRepository jobRepository, ImportJobListener listener) {
81+
return new JobBuilder("csvImporterJob", jobRepository)
82+
.incrementer(new RunIdIncrementer())
83+
.validator(new JobParametersValidator() {
84+
@Override
85+
public void validate(JobParameters parameters) throws JobParametersInvalidException {
86+
if ("Costa Rica".equals(parameters.getString("ignoreCountry"))) {
87+
throw new JobParametersInvalidException("Invalid configuration");
88+
}
89+
}
90+
})
91+
.listener(listener)
92+
.flow(csvImporterStep)
93+
.end()
94+
.build();
95+
}
96+
97+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.stacktips.app.config;
2+
3+
import com.stacktips.app.model.Customer;
4+
import lombok.extern.slf4j.Slf4j;
5+
import org.springframework.batch.core.configuration.annotation.JobScope;
6+
import org.springframework.batch.item.ItemProcessor;
7+
import org.springframework.beans.factory.annotation.Value;
8+
import org.springframework.stereotype.Component;
9+
10+
@Slf4j
11+
@JobScope
12+
@Component
13+
public class CustomJobProcessor implements ItemProcessor<Customer, Customer> {
14+
15+
private final String ignoreCountry;
16+
17+
public CustomJobProcessor(@Value("#{jobParameters['ignoreCountry']}") String ignoreCountry) {
18+
this.ignoreCountry = ignoreCountry;
19+
}
20+
21+
@Override
22+
public Customer process(Customer item) throws Exception {
23+
if (item.getCountry().equals(ignoreCountry)) {
24+
log.info("Customer ignored: {}", item.toString());
25+
}
26+
return item;
27+
}
28+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.stacktips.app.config;
2+
3+
import lombok.extern.slf4j.Slf4j;
4+
import org.springframework.batch.core.BatchStatus;
5+
import org.springframework.batch.core.JobExecution;
6+
import org.springframework.batch.core.JobExecutionListener;
7+
import org.springframework.stereotype.Component;
8+
9+
@Slf4j
10+
@Component
11+
public class ImportJobListener implements JobExecutionListener {
12+
13+
@Override
14+
public void beforeJob(JobExecution jobExecution) {
15+
log.info("Job {} started", jobExecution.getJobInstance().getJobName());
16+
}
17+
18+
@Override
19+
public void afterJob(JobExecution jobExecution) {
20+
if (jobExecution.getStatus() == BatchStatus.COMPLETED) {
21+
log.info("Job {} completed", jobExecution.getJobInstance().getJobName());
22+
} else if (jobExecution.getStatus() == BatchStatus.FAILED) {
23+
log.info("Job {} failed", jobExecution.getJobInstance().getJobName());
24+
}
25+
}
26+
}

‎spring-batch-demo/src/main/java/com/stacktips/app/config/SpringBatchConfig.java‎

Lines changed: 0 additions & 53 deletions
This file was deleted.
Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.stacktips.app.models;
1+
package com.stacktips.app.model;
22

33
import jakarta.persistence.Entity;
44
import jakarta.persistence.Id;
@@ -19,15 +19,15 @@
1919
public class Customer {
2020

2121
@Id
22-
privateString customerId;
23-
privateString firstName;
24-
privateString lastName;
25-
privateString company;
26-
privateString city;
27-
privateString country;
28-
privateString phone1;
29-
privateString phone2;
30-
privateString email;
31-
privateLocalDate subscriptionDate;
32-
privateString website;
33-
}
22+
String customerId;
23+
String firstName;
24+
String lastName;
25+
String company;
26+
String city;
27+
String country;
28+
String phone1;
29+
String phone2;
30+
String email;
31+
LocalDate subscriptionDate;
32+
String website;
33+
}
Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
package com.stacktips.app.repository;
22

3-
import com.stacktips.app.models.Customer;
3+
import com.stacktips.app.model.Customer;
44
import org.springframework.data.jpa.repository.JpaRepository;
5-
import org.springframework.stereotype.Repository;
6-
7-
@Repository
8-
public interface CustomerRepository extends JpaRepository<Customer, Integer> {
95

6+
public interface CustomerRepository extends JpaRepository<Customer, String> {
107
}

‎spring-batch-demo/src/main/java/com/stacktips/app/utils/DateUtils.java‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@
88
@UtilityClass
99
public class DateUtils {
1010

11-
public static LocalDate convertDate(String subscriptionDate) {
12-
DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd");
13-
return LocalDate.parse(subscriptionDate, dateFormat);
11+
public static LocalDate parseDate(String dateStr){
12+
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
13+
return LocalDate.parse(dateStr, formatter);
1414
}
15+
1516
}
File renamed without changes.

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /