Spring Batch:文件的批量读写Flatfile(XML,CSV,TXT)

继杨小强童鞋的《Spring Batch入门篇》之后,继续为大家分享第二篇关于Spring Batch的系列教程。

更多内容请持续关注:spring4all.com,更多spring技术干货与交流学习期待您的参与!

Spring Batch:文件的批量读写Flatfile(XML,CSV,TXT)

⏩ 该系列课程中的示例代码使用springBatch 版本为3.0.7;讲解可能会讲一些4.0.X的特性

示例代码地址:https://git.oschina.net/huicode/springbatch-learn

在这里说到FlatFile的时候,其实XML,CSV,TXT三种文件格式中XML是不属于FlatFile 的,XML在Batch中是属于StaxEvent,但是本章主要讲述SpringBatch对于文件的读写,所以放到一起说明。

本文主要讲解通过SpringBatch来处理文本格式的文件,在实际的业务中也许文本文件转DB data或者DB data转文本文件的情形更多。

说明:在spring官方文档中的说明都是基于xml配置的方式来实现ItemReader、ItemWriter、Job、Step的配置的,为了符合springBoot的配置方式,示例代码都是配置代码实现的。

使用springBatch对于 xml 文件进行读写 操作时需要引入spring-oxm 包

pom.xml配置

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-batch</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-oxm</artifactId>
    <version>4.3.8.RELEASE</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

项目结构说明

为了更好的管理代码,根据类对应的职责创建了不同的包:

  • launcher: 执行,调用job
  • processor: 负责数据的转换与处理

文件读写

使用

FlatFileItemReader,FlatFileItemWriter

帮我们做了什么?

  1. FlatFileItem 能够以固定长度进行读写(对于大文件尤为重要),开发者不用关注文件 的读写流问题

2. 对文件读写时能够保证事物

详解 FlatFileItemReader

FlatFileItemReader 是对文件读取的类,一般是对表格数据,或者文本文件数据的处理。该类的以下两个属性是必须要set的

  • setResource 指定文件资源的位置:通过ClassPathResource(类所在路径)或者FileSystemResource(文件系统所在路径)来指定要读取的文件
  • setLineMapper 行映射:指定行与实体对象之间的映射关系,示例代码使用了DefaultLineMapper
  • seEncoding 读取编码格式,默认为iso-8859-1
  • setStrict 严格模式,输入文件不存在会抛出异常,阻断当前job,默认为true
@Bean

public FlatFileItemReader<Person>csvItemReader() {

    FlatFileItemReader<Person> csvItemReader = new FlatFileItemReader<>();
    csvItemReader.setResource(new ClassPathResource("data/sample-data.csv"));
    csvItemReader.setLineMapper(new DefaultLineMapper<Person>() {{
        setLineTokenizer(new DelimitedLineTokenizer() {{
            setNames(new String[]{"name", "age"});
        }});
        setFieldSetMapper(new BeanWrapperFieldSetMapper<Person>() {{
            setTargetType(Person.class);
        }});
    }});
    return csvItemReader;

}

详解 FlatFileItemWriter

FlatFileItemWriter 是对文件的写入类,将批量数据流写入文件,该类使用必须了解下面几个方法的用法:

  • setLineAggregator 和 FlatFileItemReader 的setLineMapper方法有着相似之处,setLineAggregator方法是将对象属性聚合为字符串,聚合时根据需要设置分隔符(setDelimiter),以及对象属性对应的字符名称(setFieldExtractor)
  • LineAggregator 接口是创建对象属性聚合字符串
  • ExtractorLineAggregator 是抽象类实现LineAggregator接口。使用 FieldExtractor将对象属性转换为数组,该类的扩展类负责将数组转换字符串(doAggregate)
  • DelimitedLineAggregator 继承 ExtractorLineAggregator。是一种更常使用的聚合方式、将数组用指定符号分割,默认使用逗号
  • FormatterLineAggregator 继承 ExtractorLineAggregator。对数组字符串的最大长度,最小长度的校验,以及格式化操作
  • PassThroughLineAggregator 实现LineAggregator接口,是一种简单的聚合方式使用对象的.toString()返回值,作为聚合字符串
  • RecursiveCollectionLineAggregator 实现LineAggregator接口,将Collection集合遍历,集合的聚合通过系统行分割符分割,对象字段的聚合使用LineAggregator接口对应的聚合方法是可选择的。
  • setResource 是指定输出文件的位置,同样也是必须的,示例代码中使用了new ClassPathResource(“/data/sample-data.txt”) 实际开发中更多的是 new FilePathResource()
  • setEncoding 设置编码,默认也是 iso-8859-1
@Bean
public FlatFileItemWriter<Person> txtItemWriter() {
    FlatFileItemWriter<Person> txtItemWriter = new FlatFileItemWriter<>();
    txtItemWriter.setAppendAllowed(true);
    txtItemWriter.setEncoding("UTF-8");
    txtItemWriter.setResource(new ClassPathResource("/data/sample-data.txt"));
    txtItemWriter.setLineAggregator(new DelimitedLineAggregator<Person>() {{
        setDelimiter(",");
        setFieldExtractor(new BeanWrapperFieldExtractor<Person>() {{
            setNames(new String[]{"name", "age"});
        }});
    }});
 return txtItemWriter;
}

XML文件处理

对xml文件的处理需要引入spring-oxm包,仅对xml的输出进行详解,XML读取类似 对xml写入操作的对象为StaxEventItemWriter,与FlatFileItemWriter的使用类似,StaxEventItemWriter 与 FlatFileItemWriter都有着setResource方法,StaxEventItemWriter默认编码为utf-8

  • setRootTagName 设置根节点标签名称
  • setMarshaller 指定对象与节点 映射关系

自定义处理器ItemProcessor

ItemProcessor主要负责数据的转换与处理,将读取到的文件 转换为输出文件的对象,所以temProcessor这里不一定都是Person,实现process方法,实现数据的转换与处理。

public class PersonItemProcessor implements ItemProcessor<Person, Person> {
 @Override
 public Person process(Person person) throws Exception {
 person.setAge(person.getAge() + 1);
 person.setName(person.getName() + "-_-");
 return person;
 }
}
 

整个Job 的处理流程

  • 读取csv文件
  • 数据处理,转换
  • 输出txt文件
  • 读取txt文件
  • 数据处理,转换
  • 输出XML文件

推荐阅读

原文发布于微信公众号 - 程序猿DD(didispace)

原文发表时间:2017-06-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java架构沉思录

Spring中获取Request的方法及线程安全性分析

作者:编程迷思(Java架构沉思录做了部分修改与注释,著作权归原作者所有) 原文:https://www.cnblogs.com/kismetv/p/87572...

24950
来自专栏精讲JAVA

OutOfMemoryError异常系列之Java堆溢出

OOM异常是一种很常见的错误,但是更多的程序员对其更多的是一种迷惑,今天我就在这给大家讲讲OOM的几种情景。 Java堆溢出。 虚拟机栈和本地方法栈溢出。 方...

21750
来自专栏java工会

反射在微信公众平台开发中的应用

15140
来自专栏java工会

阿里历年经典Java面试题汇总

17960
来自专栏玄魂工作室

怎样学Python 第二十三课 模块化处理用户输入基础

大家好,今天让我们来了解一个非常有用的模块,我很久以前就没有意识到这一点,这个模块允许我们简单而有效地使用命令行参数,它不仅会为我们处理这些争论,而且如果事情不...

313100
来自专栏C/C++基础

Linux命令(36)——awk命令

AWK是一个优良的文本处理工具,Linux及Unix环境中现有的功能最强大的数据处理引擎之一。数据可以来自标准输入(stdin)、一个或多个文件,或其它命令的输...

20220
来自专栏编程心路

SSH框架之旅-spring(1)

Spring 是一个开源的轻量级 Java 开发框架,可以解决业务逻辑层和其他层的耦合太高的问题,它不仅可以用在 Java EE 上,对于 Java SE 同样...

12430
来自专栏嵌入式程序猿

freeRTOS任务创建

我们曾经在公众号里给大家推送过关于freeRTOS在NXP kinetis KV4x上的移植,得到了猿友大量的反馈,很多猿友还是感觉对基础的一些东西不懂,今天我...

42070
来自专栏python3

python 用户交互

input是个内建函数,具体用法:接收用户输入的内容,输入的字符串,接收到就是字符串;输入的是数字,接收的就是数字

18620
来自专栏Java学习之路

03 Spring框架 bean的属性以及bean前处理和bean后处理

整理了一下之前学习spring框架时候的一点笔记。如有错误欢迎指正,不喜勿喷。 上一节我们给出了三个小demo,具体的流程是这样的: 1.首先在aplicat...

33160

扫码关注云+社区

领取腾讯云代金券