Spring batch是用来处理大量数据操作的一个框架,主要用来读取大量数据,然后进行一定处理后输出成指定的形式。

  Spring batch主要有以下部分组成:

  • JobRepository       用来注册job的容器
  • JobLauncher             用来启动Job的接口
  • Job                          实际执行的任务,包含一个或多个Step
  • Step                        step包含ItemReader、ItemProcessor和ItemWriter
  • ItemReader              用来读取数据的接口
  • ItemProcessor          用来处理数据的接口
  • ItemWriter               用来输出数据的接口

以上Spring Batch的主要组成部分只需要注册成Spring的Bean即可。若想开启批处理的支持还需在配置类上使用@EnableBatchProcessing,在Spring Batch中提供了大量的ItemReader和ItemWriter的实现,用来读取不同的数据来源,数据的处理和校验都要通过ItemProcessor接口实现来完成。

Spring Boot的支持

  Spring Boot对Spring Batch支持的源码位于org.springframework.boot.autoconfigure.batch下。

  Spring Boot为我们自动初始化了Spring Batch存储批处理记录的数据库。

  spring batch会自动加载hsqldb驱动,根据需求选择去留。

下面是一个spring boot支持spring batch 的例子:

  1. 实体类

 public class Person {

     @Size(max=4,min=2) //使用JSR-303注解来校验注解
private String name; private int age; private String nation; private String address; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public String getNation() {
return nation;
} public void setNation(String nation) {
this.nation = nation;
} public String getAddress() {
return address;
} public void setAddress(String address) {
this.address = address;
}
}

  2. 校验器

 public class CsvBeanValidator<T> implements Validator<T>,InitializingBean {
private javax.validation.Validator validator;
@Override
public void afterPropertiesSet() throws Exception { //使用JSR-303的Validator来校验我们的数据,在此处进行JSR-303的Validator的初始化
ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
validator = validatorFactory.usingContext().getValidator();
} @Override
public void validate(T value) throws ValidationException {
Set<ConstraintViolation<T>> constraintViolations = validator.validate(value); //使用Validator的validate方法校验数据
if(constraintViolations.size()>0){ StringBuilder message = new StringBuilder();
for (ConstraintViolation<T> constraintViolation : constraintViolations) {
message.append(constraintViolation.getMessage() + "\n");
}
throw new ValidationException(message.toString()); } } }

  3. ItemProcessor  

 public class CsvItemProcessor  extends ValidatingItemProcessor<Person>{

     @Override
public Person process(Person item) throws ValidationException {
super.process(item); //需要执行super.process(item)才会调用自定义校验器 if(item.getNation().equals("汉族")){ //对数据做简单的处理,若民族为汉族,则数据转换成01,其余转换成02
item.setNation("01");
}else{
item.setNation("02");
}
return item;
} }

  4. Job监听(监听器要实现JobExecutionListener接口,并重写其beforeJob、afterJob方法即可)

 public class CsvJobListener implements JobExecutionListener{ 

     long startTime;
long endTime;
@Override
public void beforeJob(JobExecution jobExecution) {
startTime = System.currentTimeMillis();
System.out.println("任务处理开始");
} @Override
public void afterJob(JobExecution jobExecution) {
endTime = System.currentTimeMillis();
System.out.println("任务处理结束");
System.out.println("耗时:" + (endTime - startTime) + "ms");
} }

  5. 配置

 @Configuration    
@EnableBatchProcessing
public class CsvBatchConfig { @Bean
public ItemReader<Person> reader() throws Exception {
FlatFileItemReader<Person> reader = new FlatFileItemReader<Person>(); //使用FlatFileItemReader读取文件
reader.setResource(new ClassPathResource("people.csv")); //使用FlatFileItemReader的setResource方法设置CSV文件的路径
reader.setLineMapper(new DefaultLineMapper<Person>() {{ //在此处对CVS文件的数据和领域模型类做对应映射
setLineTokenizer(new DelimitedLineTokenizer() {{
setNames(new String[] { "name","age", "nation" ,"address"});
}});
setFieldSetMapper(new BeanWrapperFieldSetMapper<Person>() {{
setTargetType(Person.class);
}});
}});
return reader;
} @Bean
public ItemProcessor<Person, Person> processor() {
CsvItemProcessor processor = new CsvItemProcessor(); //使用自定义的ItemProcessor的实现
processor.setValidator(csvBeanValidator()); //为Processor指定校验器
return processor;
} @Bean
public ItemWriter<Person> writer(DataSource dataSource) {//Spring能让容器中已有的Bean以参数的形式注入,Spring boot已经定义了DataSource
JdbcBatchItemWriter<Person> writer = new JdbcBatchItemWriter<Person>(); //使用JDBC批处理的JdbcBatchItemWriter来写数据到数据库
writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<Person>());
String sql = "insert into person " + "(id,name,age,nation,address) "
+ "values(hibernate_sequence.nextval, :name, :age, :nation,:address)";
writer.setSql(sql); //在此设置要执行批处理的sql语句
writer.setDataSource(dataSource);
return writer;
} @Bean
public JobRepository jobRepository(DataSource dataSource, PlatformTransactionManager transactionManager)
throws Exception {
JobRepositoryFactoryBean jobRepositoryFactoryBean = new JobRepositoryFactoryBean();
jobRepositoryFactoryBean.setDataSource(dataSource);
jobRepositoryFactoryBean.setTransactionManager(transactionManager);
jobRepositoryFactoryBean.setDatabaseType("oracle");
return jobRepositoryFactoryBean.getObject();
} @Bean
public SimpleJobLauncher jobLauncher(DataSource dataSource, PlatformTransactionManager transactionManager)
throws Exception {
SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
jobLauncher.setJobRepository(jobRepository(dataSource, transactionManager));
return jobLauncher;
} @Bean
public Job importJob(JobBuilderFactory jobs, Step s1) {
return jobs.get("importJob")
.incrementer(new RunIdIncrementer())
.flow(s1) //指定step
.end()
.listener(csvJobListener()) //绑定监听器
.build();
} @Bean
public Step step1(StepBuilderFactory stepBuilderFactory, ItemReader<Person> reader, ItemWriter<Person> writer,
ItemProcessor<Person,Person> processor) {
return stepBuilderFactory
.get("step1")
.<Person, Person>chunk(65000) //批处理每次提交65000条数据
.reader(reader) //给step绑定reader
.processor(processor) //给step绑定Processor
.writer(writer) //给step绑定writer
.build();
} @Bean
public CsvJobListener csvJobListener() {
return new CsvJobListener();
} @Bean
public Validator<Person> csvBeanValidator() {
return new CsvBeanValidator<Person>();
} }

  6.application.xml

 spring.datasource.driverClassName=oracle.jdbc.OracleDriver
spring.datasource.url=jdbc\:oracle\:thin\:@localhost\:1521\:xe
spring.datasource.username=boot
spring.datasource.password=boot spring.batch.job.enabled=true logging.level.org.springframework.web = DEBUG

上面的例子是自动触发批处理的,当我们需要手动触发批处理时,需要将CsvBatchConfig类的@Configuration注解注释掉,让此配置类不再起效,新建TriggerBatchConfig配置类,内容与CsvBatchConfig完全一致,除了修改定义ItemReader这个Bean;另外,还需要修改application.xml配置文件spring.batch.job.enable=false

 @Configuration
@EnableBatchProcessing
public class TriggerBatchConfig { @Bean
@StepScope
public FlatFileItemReader<Person> reader(@Value("#{jobParameters['input.file.name']}") String pathToFile) throws Exception {
FlatFileItemReader<Person> reader = new FlatFileItemReader<Person>(); //
reader.setResource(new ClassPathResource(pathToFile)); //
reader.setLineMapper(new DefaultLineMapper<Person>() {{ //
setLineTokenizer(new DelimitedLineTokenizer() {{
setNames(new String[] { "name","age", "nation" ,"address"});
}});
setFieldSetMapper(new BeanWrapperFieldSetMapper<Person>() {{
setTargetType(Person.class);
}});
}}); return reader;
} @Bean
public ItemProcessor<Person, Person> processor() {
CsvItemProcessor processor = new CsvItemProcessor();
processor.setValidator(csvBeanValidator());
return processor;
} @Bean
public ItemWriter<Person> writer(DataSource dataSource) {
JdbcBatchItemWriter<Person> writer = new JdbcBatchItemWriter<Person>();
writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<Person>());
String sql = "insert into person " + "(id,name,age,nation,address) "
+ "values(hibernate_sequence.nextval, :name, :age, :nation,:address)";
writer.setSql(sql); //
writer.setDataSource(dataSource);
return writer;
} @Bean
public JobRepository jobRepository(DataSource dataSource, PlatformTransactionManager transactionManager)
throws Exception {
JobRepositoryFactoryBean jobRepositoryFactoryBean = new JobRepositoryFactoryBean();
jobRepositoryFactoryBean.setDataSource(dataSource);
jobRepositoryFactoryBean.setTransactionManager(transactionManager);
jobRepositoryFactoryBean.setDatabaseType("oracle");
return jobRepositoryFactoryBean.getObject();
} @Bean
public SimpleJobLauncher jobLauncher(DataSource dataSource, PlatformTransactionManager transactionManager)
throws Exception {
SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
jobLauncher.setJobRepository(jobRepository(dataSource, transactionManager));
return jobLauncher;
} @Bean
public Job importJob(JobBuilderFactory jobs, Step s1) {
return jobs.get("importJob")
.incrementer(new RunIdIncrementer())
.flow(s1)
.end()
.listener(csvJobListener())
.build();
} @Bean
public Step step1(StepBuilderFactory stepBuilderFactory, ItemReader<Person> reader, ItemWriter<Person> writer,
ItemProcessor<Person,Person> processor) {
return stepBuilderFactory
.get("step1")
.<Person, Person>chunk(65000)
.reader(reader)
.processor(processor)
.writer(writer)
.build();
} @Bean
public CsvJobListener csvJobListener() {
return new CsvJobListener();
} @Bean
public Validator<Person> csvBeanValidator() {
return new CsvBeanValidator<Person>();
} }

  控制层代码

 @RestController
public class DemoController { @Autowired
JobLauncher jobLauncher; @Autowired
Job importJob;
public JobParameters jobParameters; @RequestMapping("/read")
public String imp(String fileName) throws Exception{ String path = fileName+".csv";
jobParameters = new JobParametersBuilder()
.addLong("time", System.currentTimeMillis())
.addString("input.file.name", path)
.toJobParameters();
jobLauncher.run(importJob,jobParameters);
return "ok";
} }

Spring batch的学习的更多相关文章

  1. Spring Batch学习笔记三:JobRepository

    此系列博客皆为学习Spring Batch时的一些笔记: Spring Batch Job在运行时有很多元数据,这些元数据一般会被保存在内存或者数据库中,由于Spring Batch在默认配置是使用H ...

  2. Spring Batch学习笔记二

    此系列博客皆为学习Spring Batch时的一些笔记: Spring Batch的架构 一个Batch Job是指一系列有序的Step的集合,它们作为预定义流程的一部分而被执行: Step代表一个自 ...

  3. spring batch学习笔记

    Spring Batch是什么?       Spring Batch是一个基于Spring的企业级批处理框架,按照我师父的说法,所有基于Spring的框架都是使用了spring的IoC特性,然后加上 ...

  4. Spring Batch学习

    今天准备研究下Spring Batch,然后看了一系列资料,如下还是比较好的教程吧. 链接: http://www.cnblogs.com/gulvzhe/archive/2011/12/20/229 ...

  5. Maven+Spring Batch+Apache Commons VF学习

    Apache Commons VFS资料:例子:http://www.zihou.me/html/2011/04/12/3377.html详细例子:http://p7engqingyang.iteye ...

  6. spring batch批处理框架学习

    内如主要来自以下链接: http://www.importnew.com/26177.html http://www.infoq.com/cn/articles/analysis-of-large-d ...

  7. Spring Batch学习笔记(一)

    Spring Batch简介 Spring Batch提供了可重复使用的功能,用来处理大量数据.包括记录.跟踪,事务管理,作业处理统计,作业重启,跳过和资源管理. 此外还提供了更高级的技术服务和功能, ...

  8. Spring batch学习 详细配置解读(3)

    第一篇讲到普通job 配置 那么spring  batch 给我们提供了丰富的配置,包括定时任务,校验,复合监听器,父类,重启机制等. 下面看一个动态设置读取文件的配置 1.动态文件读取 <?x ...

  9. Spring batch学习 (1)

    Spring Batch 批处理框架 埃森哲和Spring Source研发 主要解决批处理数据的问题,包含并行处理,事务处理机制等.具有健壮性 可扩展,和自带的监控功能,并且支持断点和重发.让程序员 ...

随机推荐

  1. (3.12)mysql基础深入——mysql日志文件/其他文件(socket/pid/表结构/Innodb)

    (3.12)mysql基础深入——mysql日志文件/其他文件(socket/pid/表结构/Innodb) 关键词:mysql日志文件,mysqldumpslow分析工具 目录:日志文件的分类 1. ...

  2. vertx连接mysql数据库

    1:创建一个verticle组件 package jdbcConnection; import io.vertx.core.AbstractVerticle; import io.vertx.core ...

  3. 使用vue如何默认选中单选框

    使用了vue以后,发现这真的是一个灵活高效的框架,能够轻松实现页面的实时刷新.那么,今天先聊聊单选框的使用.一般我们使用单选框,会这么写: //HTML <input type=" c ...

  4. mount –o remount,rw /

    mount –o remount,rw / 重新挂载为已经挂载了的文件系统(以读写权限挂载),需要注意的是,挂载点必须是一个已经存在的目录,这个目录可以不为空.一般用于此目录下的文件为ro权限,需要临 ...

  5. 关闭WPS启动时显示的在线模板

    关闭WPS启动时显示的在线模板 以WPS2016为例,如下图: 操作步骤如下: ①点击在线模板页面右下方的"设置"选项 ②"设置"界面打开后,选择启动WPS默认 ...

  6. Linux系统——MySQL基础(一)

    # 数据库 ## 数据库简单的分类:(1)关系型数据库:MySQL和Oracle.Postgresql(2)非关系型数据库:Memcached和Redis(3)消息队列中间件(4)搜索引擎数据库:El ...

  7. mysql进程文件

  8. Python: 字符串搜索和匹配,re.compile() 编译正则表达式字符串,然后使用match() , findall() 或者finditer() 等方法

    1. 使用find()方法 >>> text = 'yeah, but no, but yeah, but no, but yeah' >>> text.find( ...

  9. Ignite集群管理——基于Zookeeper的节点发现

    Ignite支持基于组播,静态IP,Zookeeper,JDBC等方式发现节点,本文主要介绍基于Zookeeper的节点发现. 环境准备,两台笔记本电脑A,B.A笔记本上使用VMware虚拟机安装了U ...

  10. 干货:Java多线程详解(内附源码)

      线程是程序执行的最小单元,多线程是指程序同一时间可以有多个执行单元运行(这个与你的CPU核心有关). 在java中开启一个新线程非常简单,创建一个Thread对象,然后调用它的start方法,一个 ...