前言
在上一篇springboot整合springbatch中,我们简单介绍了springbatch的基本概念和一个基础使用demo。我们知道springbatch的强大之处在于其批处理数据时的高效、快速以及可自定义执行步骤的处理大批量数据,下面通过一个简单的案例来说说如何使用springbatch读取外部的文件,比如xml、json或其他能被解析的格式的数据导入到mysql中
执行步骤
- 定义job类
- 配置job中的执行步骤(step)
- step中再配置具体的itemReader和itemWriter
- itemReader读取数据并解析数据,读取数据的来源可以是磁盘上的日志文件,或者mysql数据或者redis数据,再通过itemWriter将读取到的数据写到指定的存储容器中
从上图可以看到,读取和写入的数据源是多样的,这样就给实际使用的时候带来了很大的选择上的便利性,下面以一个外部的csv文件为例,模拟一下上述的过程,即通过itemReader读取文件的数据,然后写到mysql的某个表中去
1、job类
注意@EnableBatchProcessing一定不要忘记,如果容易忘,建议放在启动类上面
@Configuration
@EnableBatchProcessing
public class JdbcDemoWriterConfig {
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Autowired
@Qualifier("jdbcBatchItemWriter")
private ItemWriter<Customer> itemWriter;
@Autowired
@Qualifier("dbOutPutFileReader")
private ItemReader<Customer> itemReader;
/**
* job执行入口
* @return
*/
@Bean
public Job dbOutputJob(){
return jobBuilderFactory.get("dbOutputJob")
.start(dbOutputStep())
.build();
}
/**
* 自定义job的执行步骤
* @return
*/
@Bean
public Step dbOutputStep(){
return stepBuilderFactory.get("dbOutputStep")
.<Customer,Customer>chunk(10) //设置每次操作的数据个数
.reader(itemReader)
.writer(itemWriter)
.build();
}
}
2、自定义的itemReader
通过上一篇的概念讲解,我们知道,itemReader可以理解成数据读取器,通过代码我们知道,ItemReader只是定义了一个接口,里面有很多实现类,正是这些丰富的实现类,才让程序处理的时候非常自由和灵活,可以根据不同的场景选择不同的读取器,
比如我们这里要读取一个后缀为 ".csv"的文件,就可以使用FlatFileItemReader这种读取器,代码如下:
/**
* 自定义读取
*/
@Configuration
public class DbOutputReader {
@Bean
public FlatFileItemReader<Customer> dbOutPutFileReader() {
FlatFileItemReader<Customer> reader = new FlatFileItemReader<>();
reader.setResource(new ClassPathResource("customerInit.csv"));
//设置是否跳行读取
reader.setLinesToSkip(1);
//设置外部文件的字段名
DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer();
tokenizer.setNames(new String[]{"id", "firstName", "lastName", "birthdate"});
DefaultLineMapper<Customer> lineMapper = new DefaultLineMapper();
lineMapper.setLineTokenizer(tokenizer);
//这个有点类似jdbc,将读取到的结果集放在一个resultSet中,只需要解析resultSet的字段值就可以拿到具体的值
lineMapper.setFieldSetMapper((fieldSet) -> {
Customer customer = new Customer();
customer.setId(fieldSet.readString("id"));
customer.setFirstName(fieldSet.readString("firstName"));
customer.setLastName(fieldSet.readString("lastName"));
customer.setBirthdate(fieldSet.readString("birthdate"));
return customer;
});
//检查属性设置是否完成
lineMapper.afterPropertiesSet();
reader.setLineMapper(lineMapper);
return reader;
}
}
本段代码的逻辑就是自定义了一个csv的文件读取器,将从csv文件中读取到的值,经过解析封装到一个对象的集合中并返回,其实这个FlatFileItemReader还帮助我们做了一个工作,那就是它怎么就知道文件的格式并解析成我们想要的呢?这个就是读取器内部完成的工作,有兴趣的伙伴可以研究下源码
3、自定义的itemWriter
上述通过reader读取到了csv文件的数据并封装到了对象的集合中了以后,下面就要通过itemWriter将数据写到mysql的表中,同样我们发现itemWriter也是一个接口,里面有众多的实现类,我们这里使用JdbcBatchItemWriter
这样自定义的itemWriter代码如下
/**
* 自定义writer
*/
@Configuration
public class DbOutputWriter {
@Autowired
private DataSource dataSource;
@Bean
public JdbcBatchItemWriter<Customer> jdbcBatchItemWriter(){
JdbcBatchItemWriter<Customer> jdbcBatchItemWriter = new JdbcBatchItemWriter();
//注入是数据源
jdbcBatchItemWriter.setDataSource(dataSource);
String sqlStr = "insert into customer(id,firstName,lastName,birthdate) values(:id,:firstName,:lastName,:birthdate)";
jdbcBatchItemWriter.setSql(sqlStr);
jdbcBatchItemWriter.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>());
return jdbcBatchItemWriter;
}
}
我这里提前在resources目录下,准备了一个csv文件
截取了部分内容
数据库提前创建了一张与之对应的customer表
下面启动程序,可以看到很快就执行完了,速度还是很快的,可以根据自己的电脑的配置,适当调整chunk的参数,即每次批量执行的数据条数
本篇就到此结束,最后感谢观看!