Java 如何设置简单的多行ItemReader并将批量操作作业配置为可恢复?
我试图完成一项简单的任务:Java 如何设置简单的多行ItemReader并将批量操作作业配置为可恢复?,java,spring,spring-batch,Java,Spring,Spring Batch,我试图完成一项简单的任务: 读取包含以“;”分隔的SQL查询的文本文件 在单独的事务中执行每个查询 能够从第一个失败的查询重新启动/恢复执行 我试着用SpringBatch来实现这一点。(版本2.1.8.RELEASE) 我面临的问题如下: 我未能配置一个简单的开箱即用的ItemReader,它将读取数行直到“;”,并在传递到itemreater之前将其聚合 我不需要FieldSetMapper我只是没有字段。我的输入是一个包含SQL查询的文本文件。每个查询可以包含一行或多行,查询之间用分号分隔
ItemReader
,它将读取数行直到“;”,并在传递到itemreater
之前将其聚合
我不需要FieldSetMapper
我只是没有字段。我的输入是一个包含SQL查询的文本文件。每个查询可以包含一行或多行,查询之间用分号分隔。似乎不可能在ItemReader
中定义LineMapper
而不为复杂bean指定FieldSetMapper
(我试图将beanwrapperfiedsetmapper
设置为映射到java.lang.String
,但由于下面描述的异常而失败)
问题1:如果我只想在传递给ItemWriter
之前将所有行附加到单个字符串中,为什么我需要一个字段集映射器
,并将prototypeBeanName
设置为复杂对象?当我配置fieldSetMapper
的属性prototypeBeanName
以引用java.lang.String
时,我得到一个异常,即名称的数量不等于值的数量。我调试了spring批处理代码,发现有两个值映射到一个名称:名称=%SOME_name%值={%MY_SQL_QUERY%,“;”},异常由AbstractLineTokenizer.tokenize()引发
问题2:是否可以使用开箱即用的spring批处理ItemReaders
实现行聚合?如果是,需要如何配置它们?我的配置中是否遗漏了某些内容?(见下文)
配置:
<bean id="basicParamsIncrementer" class="com.linking.core.exec.control.BasicJobParamsIncrementer" />
<batch:job id="rwBatchJob" restartable="true" incrementer="basicParamsIncrementer">
<batch:step id="processBatchStep">
<batch:tasklet transaction-manager="transactionManager" >
<batch:chunk reader="batchFileItemReader" writer="sqlBatchFileWriter"
commit-interval="1" />
</batch:tasklet>
</batch:step>
</batch:job>
<bean id="batchFileItemReader" class="org.springframework.batch.item.file.FlatFileItemReader">
<property name="resource"
value="classpath:/bat.sql.txt" />
<property name="recordSeparatorPolicy" ref="separatorPolicy" />
<property name="lineMapper">
<bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
<property name="lineTokenizer" ref="sqlTokenizer" />
<property name="fieldSetMapper" ref="sqlFieldSetMapper" />
</bean>
</property>
</bean>
<bean id="separatorPolicy" class="com.linking.core.SemiColonRecordSeparatorPolicy" />
<bean id="sqlTokenizer" class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<property name="delimiter" value=";" />
<property name="names" value="sql,eol"/>
</bean>
<bean id="sqlFieldSetMapper" class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper">
<property name="prototypeBeanName" value="sql" />
</bean>
<bean id="sql" class="com.linking.core.model.SQL" scope="prototype" />
com.linking.core.model.SQL
是一个简单的类,有两个String
类型的成员:SQL(用于查询)和eol
(用于“;”)它用于克服AbstractItemReader
返回所有到分隔符的行(作为String
)以及分隔符(在我的例子中是“;”)的情况作为值
<强>问题3:< /强>如果在只使用单步读写器方法的情况下运行大量SQL查询的任务在中间失败,那么如何从第一个失败的查询中恢复/重新启动作业?我应该通过分析上一次运行以编程方式完成它,还是可以通过作业步骤和相关开箱即用的spring批处理bean的上下文配置来实现
对于问题3,我会做几件事
- 在条目读取器中,您可以将类似“saveState”的属性传递给true
- 将“提交间隔”设置为合适的值
- 配置Spring批处理数据库,以便它可以保存状态
如果以上所有设置都已设置,并且您不使用“下一步”作为作业实例,它将在您离开的地方继续 研究使用一种新的方法。它只返回字段集,允许您直接在ItemProcessor/ItemWriter中使用它。