2016년 2월 12일 금요일

Creating batch job by spring batch

You can create batch jobs by using spring batch.
I introduce the job that reading csv file,converting the data,and inserting that to a database.























- TestApplication.java
package org.blog.test;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class TestApplication {

    public static void main(String[] args) {
        SpringApplication.run(TestApplication.class, args);
    }
}



- BatchConfig.java

package org.blog.test.batch;

import org.blog.test.batch.model.Person;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecutionListener;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableBatchProcessing
public class BatchConfig {

    @Autowired
    private ItemReader reader;

    @Autowired
    private ItemProcessor processor;

    @Autowired
    private JobExecutionListener listener;

    @Autowired
    private StepBuilderFactory stepBuilderFactory;

    @Autowired
    private JobBuilderFactory jobs;

    @Autowired
    private ItemWriter writer;

    @Bean
    public Job importUserJob(Step s1) {
        return jobs.get("importUserJob").incrementer(new RunIdIncrementer()).listener(listener).flow(s1).end().build();
    }

    @Bean
    public Step step1() {
        return stepBuilderFactory.get("step1"). chunk(10).reader(reader).processor(processor).writer(writer).build();
    }

}

- JobCompletionNotificationListener.java

package org.blog.test.batch.component;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import org.blog.test.batch.model.Person;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.listener.JobExecutionListenerSupport;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Component;

import lombok.extern.slf4j.Slf4j;

@Component
@Slf4j
public class JobCompletionNotificationListener extends JobExecutionListenerSupport {

    private final JdbcTemplate jdbcTemplate;

    private static final String SELECT_QUERY = "SELECT first_name, last_name FROM people";

    @Autowired
    public JobCompletionNotificationListener(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    @Override
    public void afterJob(JobExecution jobExecution) {
        if (jobExecution.getStatus() == BatchStatus.COMPLETED) {
            log.info("!!! JOB FINISHED! Time to verify the results");

            List results = jdbcTemplate.query(SELECT_QUERY, new RowMapper() {
                @Override
                public Person mapRow(ResultSet rs, int row) throws SQLException {
                    return new Person(rs.getString(1), rs.getString(2));
                }
            });

            for (Person person : results) {
                log.info("Found <{}> in the database.", person);
            }

        }
    }
}

- PersonItemProcessor.java

package org.blog.test.batch.component;

import lombok.extern.slf4j.Slf4j;

import org.blog.test.batch.model.Person;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class PersonItemProcessor implements ItemProcessor {

    @Override
    public Person process(final Person person) throws Exception {
        final String firstName = person.getFirstName().toUpperCase();
        final String lastName = person.getLastName().toUpperCase();

        final Person transformedPerson = new Person(firstName, lastName);

        log.info("Converting (" + person + ") into (" + transformedPerson + ")");

        return transformedPerson;
    }

}

- PersonItemReader.java

package org.blog.test.batch.component;

import org.blog.test.batch.model.Person;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper;
import org.springframework.batch.item.file.mapping.DefaultLineMapper;
import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;

@Component
public class PersonItemReader extends FlatFileItemReader implements ItemReader {

    public PersonItemReader() {

        this.setResource(new ClassPathResource("sample-data.csv"));
        this.setLineMapper(new DefaultLineMapper() {
            {
                setLineTokenizer(new DelimitedLineTokenizer() {
                    {
                        setNames(new String[] { "firstName", "lastName" });
                    }
                });
                setFieldSetMapper(new BeanWrapperFieldSetMapper() {
                    {
                        setTargetType(Person.class);
                    }
                });
            }
        });
    }
}

- PersonItemWriter.java

package org.blog.test.batch.component;

import javax.sql.DataSource;

import org.blog.test.batch.model.Person;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider;
import org.springframework.batch.item.database.JdbcBatchItemWriter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class PersonItemWriter extends JdbcBatchItemWriter implements ItemWriter {

    @Autowired
    public PersonItemWriter(DataSource dataSource) {
        this.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider());
        this.setSql("INSERT INTO people (first_name, last_name) VALUES (:firstName, :lastName)");
        this.setDataSource(dataSource);
    }
}


- Person.java

package org.blog.test.batch.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Person {

    private String lastName;

    private String firstName;
}

- sample-data.csv

Jill,Doe
Joe,Doe
Justin,Doe
Jane,Doe
John,Doe

- schema-all.sql

DROP TABLE people IF EXISTS;

CREATE TABLE people  (
    person_id BIGINT IDENTITY NOT NULL PRIMARY KEY,
    first_name VARCHAR(20),
    last_name VARCHAR(20)
);

- pom.xml


 4.0.0
 org.blog.test
 batch-project
 0.1.0

 
  org.springframework.boot
  spring-boot-starter-parent
  1.3.2.RELEASE
 

 
  
   org.springframework.boot
   spring-boot-starter-batch
  
  
   org.projectlombok
   lombok
   1.16.6
  
  
   org.hsqldb
   hsqldb
  
 

 
  
   
    org.springframework.boot
    spring-boot-maven-plugin
   
  
 


You can find the result that shows batch job is executed.

- Execution Result

2016-02-12 17:00:19.002  INFO 15192 --- [           main] o.s.b.c.l.support.SimpleJobLauncher      : Job: [FlowJob: [name=importUserJob]] launched with the following parameters: [{run.id=1}]
2016-02-12 17:00:19.017  INFO 15192 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Executing step: [step1]
2016-02-12 17:00:19.037  INFO 15192 --- [           main] o.b.t.b.component.PersonItemProcessor    : Converting (Person(lastName=Doe, firstName=Jill)) into (Person(lastName=JILL, firstName=DOE))
2016-02-12 17:00:19.037  INFO 15192 --- [           main] o.b.t.b.component.PersonItemProcessor    : Converting (Person(lastName=Doe, firstName=Joe)) into (Person(lastName=JOE, firstName=DOE))
2016-02-12 17:00:19.037  INFO 15192 --- [           main] o.b.t.b.component.PersonItemProcessor    : Converting (Person(lastName=Doe, firstName=Justin)) into (Person(lastName=JUSTIN, firstName=DOE))
2016-02-12 17:00:19.037  INFO 15192 --- [           main] o.b.t.b.component.PersonItemProcessor    : Converting (Person(lastName=Doe, firstName=Jane)) into (Person(lastName=JANE, firstName=DOE))
2016-02-12 17:00:19.037  INFO 15192 --- [           main] o.b.t.b.component.PersonItemProcessor    : Converting (Person(lastName=Doe, firstName=John)) into (Person(lastName=JOHN, firstName=DOE))
2016-02-12 17:00:19.047  INFO 15192 --- [           main] .t.b.c.JobCompletionNotificationListener : !!! JOB FINISHED! Time to verify the results
2016-02-12 17:00:19.052  INFO 15192 --- [           main] .t.b.c.JobCompletionNotificationListener : Found  in the database.
2016-02-12 17:00:19.052  INFO 15192 --- [           main] .t.b.c.JobCompletionNotificationListener : Found  in the database.
2016-02-12 17:00:19.052  INFO 15192 --- [           main] .t.b.c.JobCompletionNotificationListener : Found  in the database.
2016-02-12 17:00:19.052  INFO 15192 --- [           main] .t.b.c.JobCompletionNotificationListener : Found  in the database.
2016-02-12 17:00:19.052  INFO 15192 --- [           main] .t.b.c.JobCompletionNotificationListener : Found  in the database.
2016-02-12 17:00:19.052  INFO 15192 --- [           main] o.s.b.c.l.support.SimpleJobLauncher      : Job: [FlowJob: [name=importUserJob]] completed with the following parameters: [{run.id=1}] and the following status: [COMPLETED]


original source : https://spring.io/guides/gs/batch-processing/

댓글 없음 :

댓글 쓰기