【问题标题】:Spring batch itemwriter deleting records in mysqlSpring批处理itemwriter删除mysql中的记录
【发布时间】:2013-12-06 07:01:46
【问题描述】:

我一直在尝试 Spring Batch 示例,但无法通过 itemwriter 删除数据库中的记录。 itemreader 工作正常,但在itemwriter 我不知道如何工作,因为我是春季批次的新手,我可能会犯一些错误。我从一些示例中尝试了以下代码,但它不起作用。我必须写一些其他的类吗?

<bean id="itemWriter" class="org.springframework.batch.item.database.JdbcBatchItemWriter">
    <property name="dataSource" ref="dataSource" />
    <property name="sql">
        <!-- Why CDATA? 

             because < etc. is not allowed for xml values
             when you use &lt; xml parser will work, but
             now the sql won't because of the & spring assumes
             a placeholder, see
             - AbstractSqlPagingQueryProvider.init(...)
             - JdbcParameterUtils.countParameterPlaceholders(...)

             -->
        <value>
            <![CDATA[
                DELETE FROM TEST
                WHERE id = ? 
                and sub.id = ?
                and ... 
            ]]>
        </value>
    </property>
    <property name="itemPreparedStatementSetter">
        <bean class="...FieldSetItemPreparedStatementSetter" />
    </property>        
</bean>

ItemPreparedStatementSetter的实现

/**
 * Implementation for {@link ItemPreparedStatementSetter}, 
 * sets the values from {@link FieldSet}.
 * 
 */
public class FieldSetItemPreparedStatementSetter implements ItemPreparedStatementSetter<FieldSet> {

    /** {@inheritDoc} */
    @Override
    public void setValues(FieldSet item, PreparedStatement ps) throws SQLException {
        for (int i = 0; i < item.getValues().length; i++) {
            // PreparedStatements start with 1
            ps.setObject(i + 1, item.getValues()[i]);
        }
    }
}

我的错误是:-

 Encountered an error executing the step
java.lang.ClassCastException: com.mkyong.User cannot be cast to org.springframework.batch.item.file.transform.FieldSet
at com.mkyong.FieldSetItemPreparedStatementSetter.setValues(FieldSetItemPreparedStatementSetter.java:1)
at org.springframework.batch.item.database.JdbcBatchItemWriter$1.doInPreparedStatement(JdbcBatchItemWriter.java:190)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:589)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:617)
at org.springframework.batch.item.database.JdbcBatchItemWriter.write(JdbcBatchItemWriter.java:186)
at org.springframework.batch.core.step.item.SimpleChunkProcessor.writeItems(SimpleChunkProcessor.java:175)
at org.springframework.batch.core.step.item.SimpleChunkProcessor.doWrite(SimpleChunkProcessor.java:151)
at org.springframework.batch.core.step.item.SimpleChunkProcessor.write(SimpleChunkProcessor.java:274)
at org.springframework.batch.core.step.item.SimpleChunkProcessor.process(SimpleChunkProcessor.java:199)
at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:75)
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:395)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:131)
at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:267)
at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:77)
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:368)
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215)
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:144)
at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:253)
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:195)
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:137)
at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:64)
at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:60)
at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:152)
at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:131)
at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:135)
at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:301)
at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:134)
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:49)
at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:127)
at com.mkyong.App.run(App.java:34)
at com.mkyong.App.main(App.java:16)

Dec 06, 2013 3:50:56 PM org.springframework.batch.core.launch.support.SimpleJobLauncher$1 run
INFO: Job: [FlowJob: [name=testJob]] completed with the following parameters: [{}] and the following status: [FAILED]
Exit Status : FAILED
Exit Status : [java.lang.ClassCastException: com.mkyong.User cannot be cast to org.springframework.batch.item.file.transform.FieldSet]
Done

【问题讨论】:

  • 它不起作用”不是可接受的错误描述

标签: mysql jdbc spring-batch


【解决方案1】:

代码已“正式更正”,但您必须使用 User 而不是 FieldSet 声明您的 ItemPreparedStatementSetter,因为 ItemWriter 使用由 ItemReader 创建的相同对象;我猜你的读者会返回 User 类型的对象。

根据新的泛型有界类型替换为ItemPreparedStatementSetter&lt;User&gt;setValues(...)

【讨论】:

    【解决方案2】:

    也许,您的问题解释缺少一些信息,但在步骤定义中,您必须授予在读取时返回并传递给作者的对象的匹配。更好的解释:

    读取并创建一个 MyCustomInputPOJO:

    public class MyCustomFieldSetMapper implements FieldSetMapper<MyCustomInputPOJO> {
    
        @Override
        public MyCustomPOJO mapFieldSet(FieldSet fs) throws BindException {
            MyCustomInputPOJO pojo = new MyCustomInputPOJO();
            pojo.setAnAttribute(fs.readString("anAttribute"));
            return pojo;
        }
    }
    

    将 MyCustomInputPOJO 传递给处理器(如果有),然后转换为 MyCustomOutputPOJO:

    @Component("MyProcessor")
    public class MyCustomProcessor implements ItemProcessor<MyCustomInputPOJO, MyCustomOutputPOJO> {
        public MyCustomOutputPOJO doProcess(MyCustomInputPOJO input) {
            MyCustomOutputPOJO output = ConverterLogic.convert(input);
            return output
        }
    }
    

    现在您必须将 MyCustomOutputPOJO 传递给 JdbcBatchItemWriter 使用的 ItemPreparedStatementSetter 实现:

    public class MyCustomItemPreparedStatementSetter implements ItemPreparedStatementSetter<MyCustomOutputPOJO> {
        public void setValues(MyCustomOutputPOJO output, PreparedStatement ps) throws SQLException {
            ps.setString(1, output.getAnAttribute());
        }
    }
    

    您的步骤配置:

    <job id="MyJob">
        <step id="lerArquivoSaldos" >
                <tasklet>
                    <chunk 
                        reader="MyReader" 
                        processor = "MyProcessor"
                        writer="MyWriter" 
                        commit-interval="10" 
                    >
                    </chunk>
                </tasklet>
            </step>
    </job>
    

    其中 MyReader 和 MyProcessor 是分别引用 MyCustomFieldSetMapper 和 MyCustomItemPreparedStatementSetter 的自定义 bean。

    【讨论】:

      【解决方案3】:
      public class FieldSetItemPreparedStatementSetter implements ItemPreparedStatementSetter<com.mkyong.User > {
          /** {@inheritDoc} */
          @Override
          public void setValues(com.mkyong.User item, PreparedStatement ps) throws SQLException {
              for (int i = 0; i < item.getValues().length; i++) {
                  // PreparedStatements start with 1
                  ps.setObject(i + 1, item.getValues()[i]);
              }
          }
      }
      

      FieldSet 类替换为您的com.mkyong.User abd 分别更改setter/getter。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-10
        • 2015-09-15
        • 1970-01-01
        • 1970-01-01
        • 2015-08-19
        • 1970-01-01
        相关资源
        最近更新 更多