天天看點

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 包

https://blog.didispace.com/spring-batch-2/#pom-xml%E9%85%8D%E7%BD%AE 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>      

項目結構說明

Spring Batch:檔案的批量讀寫Flatfile(XML,CSV,TXT)

為了更好的管理代碼,根據類對應的職責建立了不同的包:

  • launcher: 執行,調用job
  • processor: 負責資料的轉換與處理

https://blog.didispace.com/spring-batch-2/#%E6%96%87%E4%BB%B6%E8%AF%BB%E5%86%99 檔案讀寫

使用 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
Spring Batch:檔案的批量讀寫Flatfile(XML,CSV,TXT)
@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 指定對象與節點 映射關系

https://blog.didispace.com/spring-batch-2/#%E8%87%AA%E5%AE%9A%E4%B9%89%E5%A4%84%E7%90%86%E5%99%A8ItemProcessor 自定義處理器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 的處理流程

  • 讀取csv檔案
  • 資料處理,轉換
  • 輸出txt檔案
  • 讀取txt檔案
  • 輸出XML檔案
Spring Batch:檔案的批量讀寫Flatfile(XML,CSV,TXT)