2

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

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

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

4

3 回答 3

3

我通常需要为每个元素进行多次插入。例如,从文件(如结构化 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>

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

于 2015-01-15T16:18:28.527 回答
0

您还可以使用具有两个委托的CompositeItemWriter 。JdbcItemWriter

于 2015-01-18T11:21:45.307 回答
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;
}
于 2017-08-22T11:24:41.193 回答