1. Spring Batch的设计图

Spring Batch-简单入门

比较重要的几个domain

  • Job 任务
  • Step 任务里包含的步骤
  • ItemReader 单个步骤里的输入(input)
  • ItemProccesor input的处理
  • ItemWriter 单个步骤里的输出(output)

ItemReader,ItemProccesor,ItemWriter这个类似于java 8里funtional编程

  • public interface Supplier
  • public interface Function<T, R>
  • public interface Consumer

2. Job

Spring Batch-简单入门

Job 执行后就产生一个JobInstance,好比类和实例的关系,1个JobInstance 可以有好多个 JobExcution

2.1 JobParameter

JobParameters就是job运行的一些算入参数

例如 通过cmd运行一个endOfDay的任务,
传入的参数是schedule.date(date)=2007/05/05,这个会构成一个JobParameter

java CommandLineJobRunner io.spring.EndOfDayJobConfiguration endOfDay schedule.date(date)=2018/05/05

上面的命令说明

CommandLineJobRunner 是spring batch提供的一个具有main方法的类,接收参数如下

  • io.spring.EndOfDayJobConfiguration 是一个Job的Spring 的@configuration类,里面包含了基本的Job的构成step
  • endOfDay是一个Job的定义,Spring的@Bean
  • schedule.date(date)=2007/05/05是参数
2.2 JobInstance 和 JobExcution的关系

下面的命令运行n次都只产生1个JobInstance

java CommandLineJobRunner io.spring.EndOfDayJobConfiguration endOfDay schedule.date(date)=2018/05/05

也就是说 JobInstance = Job + identifying JobParameters

同一个JobInstance不同次运行有不同的JobExcution,JobExcution会记录开始时间,结束时间,状态等的字段,具体的看
JobExcution包含哪些字段

2.3 spring batch的内置表来直观看上面的关系

BATCH_JOB_INSTANCE

JOB_INST_ID JOB_NAME
1 EndOfDayJob
2 EndOfDayJob

BATCH_JOB_EXECUTION_PARAMS

JOB_EXECUTION_ID TYPE_CD KEY_NAME DATE_VAL IDENTIFYING
1 DATE schedule.Date 2017-01-01 00:00:00 true
2 DATE schedule.Date 2017-01-01 00:00:00 true
3 DATE schedule.Date 2017-01-02 00:00:00 true

BATCH_JOB_EXECUTION

JOB_EXECUTION_ID JOB_INST_ID START_TIME END_TIME STATUS
1 1 2017-01-01 21:00 2017-01-01 21:30 FAILED
2 1 2017-01-02 21:00 2017-01-02 21:30 COMPLETED
3 2 2017-01-02 21:31 2017-01-02 22:29 COMPLETED

spring batch 内置表的关系图如下
Spring Batch-简单入门

3. Step

Spring Batch-简单入门

每次step触发后就会产生一个stepExecution,step不像job,是没有stepinstance的。对于stepExecution,对应的表有

  • BATCH_STEP_EXECUTION 用来记录开始时间,结束时间,状态等字段记录
  • BATCH_STEP_EXECUTION_CONTEXT 通过
    executionContext.putLong(getKey(LINES_READ_COUNT), reader.getPosition());可以表里存入一些记录

4.Sample

从一个文件中读取数据,封装成Person对象并打印

Person.txt

1,Rechard,20
2,James,30
3,Cury,28
4,Durant,26

Person.java

public class Person {
    private int id;
    private String name;
    private int age;
    //getter and setter
    
}

Batch的@Configuration

Job里配置一个Step

  • step里的reader 从文件Person.txt中读数据,每一行代表 Person的信息,封装成Person对象
  • step里的Processor
    将Person打印出来
@Configuration
@ComponentScan("rechard.learn.springbatch.sample.simple")
@EnableBatchProcessing
public class SimpleBatchConfiguration {

    @Autowired
    JobBuilderFactory jobBuilders;

    @Autowired
    private StepBuilderFactory steps;

    @Autowired

//配置1个Job,job里只有1个step
    @Bean
    public Job simpleJob(Step step){
        return jobBuilders.get("simpleJob").start(step).build();
    }
//step 里的reader和writer
    @Bean
    protected Step step(ItemReader<String> reader,
                         ItemWriter<Person> writer) {
        return steps.get("step1")
                .<String, Person> chunk(10)
                .reader(reader)
                .writer(writer)
                .build();
    }
    
    //reader 使用sprinb batch内置的FlatFileItemReader,读取1行并封装成为1个Person 对象
    @Bean
    protected ItemReader<String> reader(){
        FlatFileItemReader reader=new FlatFileItemReader();
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(new File("E:\\person.txt"));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        reader.setResource( new InputStreamResource(fis));
        reader.setLineMapper((line,number)->{
            String[] str = line.split(",");
            Person p = new Person();
            p.setId(Integer.parseInt(str[0]));
            p.setName(str[1]);
            p.setAge(Integer.parseInt(str[2]));
            return p;
        });
        return reader;
    }
//reader 则简单的打印出来,这里是ItemWriterAdapter,这个类主要是设置一个代理类来帮助打印,代理类就是真实的处理Person逻辑的类PersonProcessor
    @Bean
    protected ItemWriter<Person> writer(){
        ItemWriterAdapter<Person> adapter = new ItemWriterAdapter();
        adapter.setTargetMethod("print");
        adapter.setTargetObject(new PersonProcessor());
        return adapter;
    }

}

PersonProcessor

public class PersonProcessor {
    public void print(Person p){
        System.out.println(p.toString());
    }
}

main的启动类

public class SimpleDemo {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx =  new AnnotationConfigApplicationContext();
        ctx.register(SimpleBatchConfiguration.class);
        ctx.refresh();
        JobLauncher launcher = (JobLauncher)ctx.getBean("jobLauncher");
        JobParameters parameters = new JobParameters();
        try {
            launcher.run((Job)ctx.getBean("simpleJob"),parameters);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

打印出来的结果

Person{id=1, name='Rechard', age=20}
Person{id=2, name='James', age=30}
Person{id=3, name='Cury', age=28}
Person{id=4, name='Durant', age=26}

相关文章:

  • 2022-12-23
  • 2021-10-28
  • 2021-08-19
  • 2022-12-23
  • 2021-06-16
  • 2021-04-07
  • 2021-04-05
  • 2021-08-05
猜你喜欢
  • 2021-05-02
  • 2021-10-03
  • 2021-06-21
  • 2022-12-23
  • 2021-12-01
  • 2021-09-06
相关资源
相似解决方案