大家都知道,传统Spring-batch能够很好的处理批量任务,其中,提供的trunk组件(batch:trunk)能够处理行文本或者数据库的普通读写操作。下面这个例子可以读写基本的规范数据文件:
<batch:step id="analyseInfo"> <batch:tasklet transaction-manager="transactionManager"> <batch:chunk reader="wxReader" writer="wxWriter" commit-interval="10"></batch:chunk> </batch:tasklet> </batch:step> <!-- wx Detail --> <bean id="wxReader" class="org.springframework.batch.item.file.FlatFileItemReader" scope="step"> <property name="resource" value="file:#{jobParameters['filename']}"></property> <property name="encoding" value="UTF-8"></property> <property name="comments" value="#{'#'}"></property> <property name="lineMapper" ref="wxMapper"></property> <property name="linesToSkip" value="1"></property> </bean> <bean id="wxWriter" class="com.secondgame.demo_service.demo.batch.task.WxWriter" scope="step">
上述代码中,wxReader负责解析源文件:
resource配置源文件的地址,
encoding配置文件的编码方式,
comments配置注释行的开头,可以跳过注释行,本文例子跳过以#开头的注释行,不进行处理
lineMapper负责具体的处理文件的类,后文会介绍
lineToSkip用来指定跳过处理文本的头N行,本例跳过1行
lineMapper的配置
<bean id="wxMapper" class="org.springframework.batch.item.file.mapping.DefaultLineMapper"> <property name="lineTokenizer" ref="wxMultiTokenizer"></property> <property name="fieldSetMapper"> <bean class="com.secondgame.demo_service.demo.batch.task.WxFileSetMapper"> </bean> </property> </bean> <bean id="wxTokenizer" class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer" scope="step"> <property name="delimiter" value=","></property> <property name="names"> <list> <value>tradeTime</value> <value>pubAccountId</value> <value>merchantId</value> <value>subMerchantId</value> <value>deviceId</value> <value>wxOrderId</value> <value>merchantOrderId</value> <value>userTag</value> <value>tradeType</value> <value>tradeStatus</value> <value>payerBank</value> <value>capitalType</value> <value>totalAmount</value> <value>enterpriseRedAmount</value> <value>wxRefundId</value> <value>merchantRefundId</value> <value>refundAmount</value> <value>enterpriseRedRefundAmount</value> <value>refundType</value> <value>refundStatus</value> <value>goodsName</value> <value>merchantData</value> <value>fee</value> <value>feeRate</value> </list> </property> </bean>
该配置中,使用org.springframework.batch.item.file.transform.DelimitedLineTokenizer进行文件解析,能够将解析出来的每一行利用类com.secondgame.demo_service.demo.batch.task.WxFileSetMapper进行处理。
实际应用中,数据源没有想象的那么“整齐”,可以通过离线数据清洗(各种脚本)的方式将数据进行预处理。但对于基本整齐的文件,可以采用spring-batch提供的行解析器org.springframework.batch.item.file.transform.PatternMatchingCompositeLineTokenizer进行处理。该解析器不受限于一种解析器,可以根据通配符配置,对不同的行进行不同的解析,假设文本文件有如下结构:
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24 1,2,3,4,5 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24
该文件每行数据由逗号分隔,但是存在不规则的行(或者有特殊意义,作者遇到的情况是,对账明细单最后有汇总项,而且无法通过前缀区分)。该文本在上述代码配置中,会直接在解析第三行的地方报错:需要24个参数,实际只有5个。
笔者想到的解决方案有如下几种:
1. 与处理文件,把不规则的第三行处理掉
2. 补齐第三行的数据,凑足24个内容。
两者都需要额外的处理数据过程,而使用前文介绍的PatternMatchingCompositeLineTokenizer则可以直接处理该种情况。
部分实现的代码如下(仅体现核心思想,直接拷贝代码无法使用,实际工程需要额外配置文件):
<bean id="wxMapper" class="org.springframework.batch.item.file.mapping.DefaultLineMapper"> <property name="lineTokenizer" ref="wxMultiTokenizer"></property> <property name="fieldSetMapper"> <bean class="com.secondgame.demo_service.demo.batch.task.WxFileSetMapper"> </bean> </property> </bean> <bean id="wxMultiTokenizer" class="org.springframework.batch.item.file.transform.PatternMatchingCompositeLineTokenizer" scope="step"> <!-- <property name="delimiter" value=","></property> --> <property name="tokenizers"> <map> <entry key="*,*,*,*,*" value-ref="wxTokenizerTail"></entry> <entry key="*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*" value-ref="wxTokenizer"></entry> </map> </property> </bean> <bean id="wxTokenizer" class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer" scope="step"> <property name="delimiter" value=","></property> <property name="names"> <list> <value>tradeTime</value> <value>pubAccountId</value> <value>merchantId</value> <value>subMerchantId</value> <value>deviceId</value> <value>wxOrderId</value> <value>merchantOrderId</value> <value>userTag</value> <value>tradeType</value> <value>tradeStatus</value> <value>payerBank</value> <value>capitalType</value> <value>totalAmount</value> <value>enterpriseRedAmount</value> <value>wxRefundId</value> <value>merchantRefundId</value> <value>refundAmount</value> <value>enterpriseRedRefundAmount</value> <value>refundType</value> <value>refundStatus</value> <value>goodsName</value> <value>merchantData</value> <value>fee</value> <value>feeRate</value> </list> </property> </bean> <bean id="wxTokenizerTail" class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer" scope="step"> <property name="delimiter" value=","></property> <property name="names"> <list> <value>totalCount</value> <value>totalAmount</value> <value>refundAmount</value> <value>enterpriseRedRefundAmount</value> <value>fee</value> </list> </property> </bean>
上述代码实现了两个行解析器,分别解析24个数据和5个数据的情况,其他情况可以继续增加行解析器即可。
如果数据文件情况更加复杂,可以考虑自定义行解析器,实现自定义功能,这个笔者并没有进一步的研究,以后可以再尝试,本文思路来自于stackoverflow:
http://stackoverflow.com/questions/27504722/how-to-custom-spring-batch-delimitedlinetokenizer
不过这个作者的代码通配符部分我实现*全量替代过不去,还需要进一步看源码。
相关推荐
Spring-batch Demo.zip Spring-batch Demo.zip Spring-batch Demo.zip
spring-batch4.0.0 batch spring-batch集成 spring-batch.jar
批处理文件 spring-batch 所需要的jar包
spring batch 3.0.5,官方下载包。
spring-batch-admin-1.3.0.RELEASE,很多小朋友找不到 ,所以上传下
spring-batch-2.2.0.RELEASE-no-dependencies
Spring-batch简介.pdf Spring-batch简介.pdf Spring-batch简介.pdf
spring-batch+quartz处理mysql数据示例,功能:定时从mysql里读取数据,进行处理,再存入到mysql
spring-batchr的分区示例的简单实现。
springbatch批处理框架,很好,帮助大家熟悉应用批处理的业务,可以一起来看看,spring的核心组件之一,我们一起来hold住
spring-batch-reference。
Spring-Batch-Excel
这是一个java工程的demo,spring-batch 3.0.7所需的jar都在其中,需要自己建数据库,将两个sql文件运行(此步骤是必须的),然后直接run App.java即可。控制台会显示completed done,数据库的表中会有记录。
Spring Batch流程介绍: 每个Batch都会包含一个Job。Job就像一个容器,这个容器里装了若干Step,Batch中实际干活的也就是这些Step,至于Step干什么活,无外乎读取数据,处理数据,然后将这些数据存储起来...
初始化数据库:找到目录:/ spring-batch-admin-backend / src / main / db,里面有两个文件,一个是数据库创建脚本,一个是表结构+数据的脚本,先执行创建库的,如果想在已经存在的库里面运行程序,可以省略这一步...
spring-batch-2.1.9.RELEASE-no-dependencies
Spring-Batch-Excel Spring Batch扩展包含基于Excel的ItemReader实现。 它支持读取XLS和XLSX文件,后者还具有(实验性)流支持。 PoiItemReader具有最多的功能,但同时也是最耗费内存的,并且可能导致大型XLS(X)...
Spring批测试 这是一个用于存储Spring批处理...java -jar target/spring-batch- * .jar 如果有一些错误,建议您使用debug标志运行: java -jar target/spring-batch- * .jar --debug 至少需要Maven 3.2和Java 1.8。
spring-batch-master.zip
bank-spring-batch:具有多处理器的Spring Batch项目