使用Spring Batch ItemProcessor处理一些XML文件之后。 ItemProcessor返回如下项目:
MetsModsDef
{
int id;
String title;
String path;
Properties identifers;
....
}
现在我需要将这些项目保存到数据库中,以便 (id,title,path)将进入"工作"表
和所有属性存储在"标识符"字段进入"键/值" -Table调用"标识符" (work,identitytype,identityValue)
我怎么能实现这个目标?
目前我正在使用CompositeItemWriter来拆分对象并将其写入两个表中,如下所示:
public ItemWriter<MetsModsDef> MultiTableJdbcWriter(@Qualifier("dataSource") DataSource dataSource) {
CompositeItemWriter<MetsModsDef> cWriter = new CompositeItemWriter<MetsModsDef>();
JdbcBatchItemWriter hsqlWorkWriter = new JdbcBatchItemWriterBuilder()
.itemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>())
.sql("INSERT INTO work (id, title, path,enabled) VALUES (:id, :title,:path,1)" )
.dataSource(dataSource)
.build();
JdbcBatchItemWriter hsqlIdentifierWriter = new JdbcBatchItemWriterBuilder()
.itemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>())
.sql("INSERT INTO identity (work, identitytype, identityValue) VALUES (:work, :identitytype, :identityValue)" )
.dataSource(dataSource)
.build();
List<ItemWriter<? super MetsModsDef>> mWriter = new ArrayList<ItemWriter<? super MetsModsDef>>();
mWriter.add(hsqlWorkWriter);
mWriter.add(hsqlIdentifierWriter);
cWriter.setDelegates(mWriter);
但这对于属性列表不起作用,因为(work,identitytype,identityValue)不是我的域对象MetModsDef的一部分,它只包含一个应该进入Identifier表的属性映射。
我在写入文件时找到了如何做的建议, 甚至使用Spring-Integration Read one record/item and write multiple records/items using spring batch的分割器模式 但是当我通过jdbc或hibernate写出来时,我仍然不确定如何实际做到这一点(我假设它会类似) 谢谢你的建议!
答案 0 :(得分:0)
如果有人感兴趣:过了一段时间我想出了自己的解决方案: 我在互联网上找到了一个扩展HibernateItemWriter(用于hibernate写入):
Spring-Batch Multi-line record Item Writer with variable number of lines per record 但我不想扩展课程,所以我不得不提出自己的课程(基于我可以在互联网上研究的内容)。
我不确定它有多好,以及如何处理事务或回滚(可能不好)。但现在它是我唯一拥有的。所以如果你也需要一个,或者对如何改进它有意见。甚至有一个更好的。非常欢迎你。 我创建了自己的IdentifierListWriter,它为每个MetsModsDef项创建了类似于键/值对的对象(这里每个对称为“identitifier”),并使用从配置传递给它的JdbcBatchItemWriter identifierWriter将它们全部写出来
public class IdentifierListWriter implements ItemWriter<MetsModsDef>
{
private ItemWriter<Identifier> _identifierWriter;
public IdentifierListWriter ( JdbcBatchItemWriter<Identifier> identifierWriter )
{
_identifierWriter= identifierWriter;
}
@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
public void write(List<? extends MetsModsDef> items) throws Exception
{
// Main Table WRITER
for ( MetsModsDef item : items )
{
ArrayList<Identifier> ids = new ArrayList<Identifier>();
for(String key : item.getAllIds().stringPropertyNames())
{
ids.add(new Identifier(item.getAllIds().getProperty(key),
key, item.getId()));
}
_identifierWriter.write(ids);
}
}
}
在java配置中,我创建了两个jdbcBatchItemWriter Beans。一个用于“工作”表,一个用于“标识符”表。 IdentifierListWriter bean和CompositeItemWriter MultiTableJdbcWriter Bean使用它们来写出对象
@Bean
@Primary
public ItemWriter<MetsModsDef> MultiTableJdbcWriter(@Qualifier("dataSource") DataSource dataSource) {
IdentifierListWriter identifierListWriter = new IdentifierListWriter(identifierWriter(dataSource) );
CompositeItemWriter cWriter = new CompositeItemWriter();
cWriter.setDelegates(Arrays.asList(hsqlWorkWriter(dataSource),identifierListWriter));
return cWriter;
}
@Bean
public JdbcBatchItemWriter<MetsModsDef> hsqlWorkWriter(@Qualifier("dataSource") DataSource dataSource) {
return new JdbcBatchItemWriterBuilder<MetsModsDef>()
.itemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>())
.sql("INSERT INTO work (id, title, path,enabled) VALUES (:id, :title,:path,1)")
.dataSource(dataSource)
.build();
}
@Bean
public JdbcBatchItemWriter<Identifier> identifierWriter(@Qualifier("dataSource") DataSource dataSource) {
return new JdbcBatchItemWriterBuilder()
.itemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>())
.sql("INSERT INTO identifier (identifier, type, work_id) VALUES ( :identifier, :type, :work)")
.dataSource(dataSource)
//.afterPropertiesSet()
.build();
}
然后从Step:
调用multiTableJdbcWriter @Bean
public Step step1(ItemWriter<MetsModsDef> multiTableJdbcWriter) {
return stepBuilderFactory.get("step1")
.<StreamSource, MetsModsDef>chunk(1)
.reader(new MetsModsReader())
.processor(metsModsFileProcessor())
.writer(multiTableJdbcWriter)