如何执行关于Spring批处理JdbcItemWriter的多个SQL

时间:2013-09-05 16:24:54

标签: spring spring-batch

我必须使用Spring批处理将数据写入多个表。例如,我有两个表:用户表和信息表。

我不想使用存储过程,但JdbcItemwriter不允许执行多个SQL。我想在JdbcItemWriter中执行多个SQL。

我正在寻找有关执行此操作的最佳方式的指示和一般建议。

3 个答案:

答案 0 :(得分:1)

我通常需要为每个元素执行多次插入。例如,从文件读取时(如结构化XML)。 为此,我通常实现一个特定的ItemWriter类,其中属性是每个表的特定JdbcItemWriter类。这是一个例子:

package my.package.writer;

import  my.package.model.tbl.MyMainObject;
import  my.package.model.tbl.MySubObject1;
import  my.package.model.tbl.MySubObject2;
import org.springframework.batch.item.ItemWriter;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

public class MainMultipleWriter implements ItemWriter<PkjwdPolizze>
{

    private CounterBean                    counterBean;
    private ItemWriter<MyMainObject>       writerMyMainObject;
    private ItemWriter<MySubObject1>       writerSubObject1;
    private ItemWriter<MySubObject2>       writerSubObject2;

    @Transactional(readOnly = false, propagation = Propagation.REQUIRED)
    public void write(List<? extends MyMainObject> items) throws Exception
    {
        // Main Table WRITER
        writerMyMainObject.write(items);

        // Secondary Table WRITERS
        for (MyMainObject item : items)
        {
            writerSubObject1.write(item.getLstMySubObject1());
            writerSubObject2.write(item.getLstMySubObject2());              
        }
    }
}

在此之后,您将作业配置为使用MultiWriter课程而不是简单的JdbcItemWriter。以下是该配置的示例:

<!-- job -->
<batch:job id="myJob" job-repository="jobRepository" restartable="false">
    <batch:step id="myStep" >
        <batch:tasklet transaction-manager="transactionManager">
            <batch:chunk commit-interval="2500" reader="myReader"
                processor="myProcessor" writer="myMultiWriterBean" />
        </batch:tasklet>
    </batch:step>
</batch:job>

<!-- Writers -->
<bean id="myMainObjectWriter" class="org.springframework.batch.item.database.JdbcBatchItemWriter">
    <property name="itemPreparedStatementSetter">
        <bean class="my.package.setters.MyMainObjectStatementSetter"></bean>
    </property>
    <property name="sql" value="--insert_statement--" />
    <property name="dataSource" ref="dataSource" />
</bean>

<bean id="mySubObject1Writer" class="org.springframework.batch.item.database.JdbcBatchItemWriter">
    <property name="itemPreparedStatementSetter">
        <bean class="my.package.setters.MySubObject1StatementSetter"></bean>
    </property>
    <property name="sql" value="--insert_statement--" />
    <property name="dataSource" ref="dataSource" />
</bean>

<bean id="mySubObject2Writer" class="org.springframework.batch.item.database.JdbcBatchItemWriter">
    <property name="itemPreparedStatementSetter">
        <bean class="my.package.setters.MySubObject2StatementSetter"></bean>
    </property>
    <property name="sql" value="--insert_statement--" />
    <property name="dataSource" ref="dataSource" />
</bean>

<bean id="myMultiWriterBean" class="my.package.writer.MainMultipleWriter">
    <property name="writerMyMainObject" ref="mySubObject1Writer" />
    <property name="writerSubObject1" ref="mySubObject2Writer" />
    <property name="writerSubObject2" ref="mySubObject2Writer" />
</bean>

我认为这是一个更清晰的实现,因为您尊重块结构,而不必担心回滚,事务和数据完整性。

答案 1 :(得分:0)

您还可以使用CompositeItemWriter和两名JdbcItemWriter代表。

答案 2 :(得分:0)

查看CompositeItemWriter配置示例,如下所示:

@Bean
@StepScope
public JdbcBatchItemWriter<YourBeanDto> jdbcUpdateTable1Writer(DataSource dataSource) {
    JdbcBatchItemWriter<YourBeanDto> jdbcBatchItemWriter = new JdbcBatchItemWriter<>();
    jdbcBatchItemWriter.setAssertUpdates(true);
    jdbcBatchItemWriter.setDataSource(dataSource);
    jdbcBatchItemWriter.setSql(" Update .... ");
    jdbcBatchItemWriter.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<YourBeanDto>());
    return jdbcBatchItemWriter;
}

@Bean
@StepScope
public JdbcBatchItemWriter<YourBeanDto> jdbcInsertTable2Writer(DataSource dataSource) {
    JdbcBatchItemWriter<YourBeanDto> jdbcBatchItemWriter = new JdbcBatchItemWriter<>();
    jdbcBatchItemWriter.setDataSource(dataSource);
    jdbcBatchItemWriter.setSql(" Insert .... ");
    jdbcBatchItemWriter.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<YourBeanDto>());
    return jdbcBatchItemWriter;
}

@Bean
@StepScope
public CompositeItemWriter<YourBeanDto> compositeItemWriter(
    @Qualifier("jdbcUpdateTable1Writer") JdbcBatchItemWriter<YourBeanDto> jdbcUpdateTable1Writer,
    @Qualifier("jdbcInsertTable2Writer") JdbcBatchItemWriter<YourBeanDto> jdbcInsertTable2Writer) {
    CompositeItemWriter<YourBeanDto> writer = new CompositeItemWriter<>();
    writer.setDelegates(Arrays.asList(jdbcUpdateTable1Writer, jdbcInsertTable2Writer));
    return writer;
}