Spring Batch - XML to DB - 如何在多次运行中始终保持新数据(XML文件中存在的任何内容)?

时间:2016-07-24 17:51:07

标签: java spring-batch spring-batch-admin

我正在开发Spring Batch - XML to DB example。在此示例中,我想将XML数据加载到DB中。按照当前的实现,如果我运行主程序,那么XML数据就会成功加载到DB中,我再次运行主程序数据被加载到DB中(以前的运行输出 - 对于第二次运行,它都是重复的)。如果我不想保留旧数据,即每当我运行主代码时,我应该将新数据(无论是否存在于数据库中)放入表中,该怎么办?我需要在DB中更改哪些配置?

弹簧分批context.xml中

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:batch="http://www.springframework.org/schema/batch" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/batch
        http://www.springframework.org/schema/batch/spring-batch.xsd
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    <import resource="classpath:context-datasource.xml"/>
    <!-- ============= ItemReader which reads data from XML file ============= -->
    <bean id="xmlItemReader" class="org.springframework.batch.item.xml.StaxEventItemReader">
        <property name="resource" value="classpath:examResult.xml" />
        <property name="fragmentRootElementName" value="ExamResult" />
        <property name="unmarshaller">
            <bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
                <property name="classesToBeBound">
                    <list>
                        <value>com.websystique.springbatch.model.ExamResult</value>
                    </list>
                </property>
            </bean>
        </property>
    </bean>
    <!-- ================ ItemWriter which writes data to database ================= -->
    <bean id="databaseItemWriter" class="org.springframework.batch.item.database.JdbcBatchItemWriter">
        <property name="dataSource" ref="dataSource" />
        <property name="sql">
            <value>
                <![CDATA[        
                    insert into EXAM_RESULT(STUDENT_NAME, DOB, PERCENTAGE) values (?, ?, ?)
                ]]>
            </value>
        </property>
        <!-- We need a custom setter to handle the conversion between Jodatime LocalDate and MySQL DATE -->
        <property name="ItemPreparedStatementSetter">
            <bean class="com.websystique.springbatch.ExamResultItemPreparedStatementSetter" />
        </property>
  </bean>
    <!-- Optional ItemProcessor to perform business logic/filtering on the input records -->
    <bean id="itemProcessor" class="com.websystique.springbatch.processor.ExamResultItemProcessor" />
    <!-- Optional JobExecutionListener to perform business logic before and after the job -->
    <bean id="jobListener" class="com.websystique.springbatch.utils.ExamResultJobListener" />
    <!-- ==================== Actual Job ========================= -->
    <batch:job id="examResultJob">
        <batch:step id="step1">
            <batch:tasklet transaction-manager="transactionManager">
                <batch:chunk reader="xmlItemReader" writer="databaseItemWriter" processor="itemProcessor" commit-interval="10" />
            </batch:tasklet>
        </batch:step>
        <batch:listeners>
            <batch:listener ref="jobListener" />
        </batch:listeners>
    </batch:job>
</beans>

2 个答案:

答案 0 :(得分:1)

为了满足您的要求,您只需要更改查询。

您应该将学生姓名作为表格中的主键 然后在配置文件中更改查询。

"insert into EXAM_RESULT(STUDENT_NAME, DOB, PERCENTAGE) 
values (?, ?, ?) on DUPLICATE KEY UPDATE DOB = ? ,PERCENTAGE=?"

将值提供给位置参数 ExamResultItemPreparedStatementSetter

希望这会对你有帮助......

答案 1 :(得分:0)

添加新的tasklet作为第一步,在导入之前从表中删除数据 您可以使用Tasklet

来解决问题
public class SQLStmtTasklet implements Tasklet{
  private DataSource dataSource;
  private String sql;

  public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
    //  Execute your sql statement
    return RepeatStatus.FINISHED;       
  }
}

这是Takslet的骨架;只需添加访问器并填充execute()方法。