我必须使用 Spring 批处理将数据写入多个表。例如,我有两个表:用户表和信息表。
我不想使用存储过程,但JdbcItemwriter
不允许执行多个 SQL。我想在JdbcItemWriter
.
我正在寻找有关执行此操作的最佳方式的指针和一般建议。
我必须使用 Spring 批处理将数据写入多个表。例如,我有两个表:用户表和信息表。
我不想使用存储过程,但JdbcItemwriter
不允许执行多个 SQL。我想在JdbcItemWriter
.
我正在寻找有关执行此操作的最佳方式的指针和一般建议。
我通常需要为每个元素进行多次插入。例如,从文件(如结构化 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>
我认为这是一个更干净的实现,因为您尊重块结构并且不必担心回滚、事务和数据完整性。
您还可以使用具有两个委托的CompositeItemWriter 。JdbcItemWriter
查看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;
}