SpringBatch Flatfile(XML,CSV,TXT) 文件的批量读写

SpringBatch 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配置的方式来实现ItemReaderItemWriterJobStep的配置的,为了符合springBoot的配置方式,示例代码都是配置代码实现的

一、pom.xml 配置

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

<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>

二、项目结构说明

image.png

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

  • 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<T> 集合遍历,集合的聚合通过系统行分割符分割,对象字段的聚合使用LineAggregator接口对应的聚合方法是可选择的。

  • setResource 是指定输出文件的位置,同样也是必须的,示例代码中使用了new ClassPathResource("/data/sample-data.txt") 实际开发中更多的是 new FilePathResource()

  • setEncoding 设置编码,默认也是 iso-8859-1

    image.png

示例代码:

@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 指定对象与节点 映射关系

示例代码:

@Bean
    public StaxEventItemWriter<Person> xmlItemWriter() {
        StaxEventItemWriter<Person> xmlItemWriter = new StaxEventItemWriter<>();
        xmlItemWriter.setRootTagName("root")
        xmlItemWriter.setEncoding("UTF-8");
        xmlItemWriter.setResource(new ClassPathResource("/data/sample-data.xml"));
        xmlItemWriter.setMarshaller(new XStreamMarshaller() {{
            Map<String, Class<Person>> map = new HashMap<>();
            map.put("person",Person.class);
            setAliases(map);
        }});
        return xmlItemWriter;
    }

四、自定义处理器ItemProcessor

ItemProcessor主要负责数据的转换与处理,将读取到的文件 转换为输出文件的对象,所以temProcessor<Person, Person>这里不一定都是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 的处理流程

image.png

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,902评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,037评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,978评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,867评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,763评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,104评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,565评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,236评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,379评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,313评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,363评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,034评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,637评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,719评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,952评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,371评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,948评论 2 341

推荐阅读更多精彩内容