Java 如何设置简单的多行ItemReader并将批量操作作业配置为可恢复?

Java 如何设置简单的多行ItemReader并将批量操作作业配置为可恢复?,java,spring,spring-batch,Java,Spring,Spring Batch,我试图完成一项简单的任务: 读取包含以“;”分隔的SQL查询的文本文件 在单独的事务中执行每个查询 能够从第一个失败的查询重新启动/恢复执行 我试着用SpringBatch来实现这一点。(版本2.1.8.RELEASE) 我面临的问题如下: 我未能配置一个简单的开箱即用的ItemReader,它将读取数行直到“;”,并在传递到itemreater之前将其聚合 我不需要FieldSetMapper我只是没有字段。我的输入是一个包含SQL查询的文本文件。每个查询可以包含一行或多行,查询之间用分号分隔

我试图完成一项简单的任务:

  • 读取包含以“;”分隔的SQL查询的文本文件
  • 在单独的事务中执行每个查询
  • 能够从第一个失败的查询重新启动/恢复执行
  • 我试着用SpringBatch来实现这一点。(版本2.1.8.RELEASE) 我面临的问题如下:

    我未能配置一个简单的开箱即用的
    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中使用它。