我在这个论坛上找到了许多使用多个作家的例子。大多数,如果不是全部的话,答案集中在复合作者和分类作者身上。
业务需求:从输入文件中读取一行。这一行将包含多个字段(超过50个),需要写入它们自己的数据库表(理论上代表不同的类)。
----- claimwriter(write to claim table)
/
/
claimlineitemprocessor -----
\
\
----- pharmacywriter(write to pharmacy table)
我使用了一个字段集映射器来创建表示索赔行(ClaimLine)的对象。大多数字段是对文件中数据的简单映射,但少数字段需要更改其格式或相关字段映射逻辑。
基本item writer代码如下所示:
@SuppressWarnings({ "unchecked", "rawtypes" })
@Bean
public ItemWriter<ClaimLine> writer() {
CompositeItemWriter<ClaimLine> cWriter = new CompositeItemWriter<ClaimLine>();
JdbcBatchItemWriter claimWriter = new JdbcBatchItemWriter();
claimWriter.setItemSqlParameterSourceProvider(new ClaimItemSqlParameterSourceProvider());
claimWriter.setSql( // would like to insert into pharmacy table);
claimWriter.setDataSource(dataSource);
claimWriter.afterPropertiesSet();
JdbcBatchItemWriter pharmacyWriter = new JdbcBatchItemWriter();
pharmacyWriter.setItemSqlParameterSourceProvider(new PharmacyItemSqlParameterSourceProvider());
pharmacyWriter.setSql( // would like to insert into pharmacy table);
pharmacyWriter.setDataSource(dataSource);
pharmacyWriter.afterPropertiesSet();
List<ItemWriter<? super ClaimLine>> mWriter = new ArrayList<ItemWriter<? super ClaimLine>>();
mWriter.add(claimWriter);
mWriter.add(pharmacyWriter);
cWriter.setDelegates(mWriter);
// other code
return cWriter;
};
在创建自定义源提供程序时,它们中的每一个似乎都是预期的,因为这个类已经映射到输入行,并且包含我想要发送到各个表的值。
这就是我现在陷入困境的原因,我认为我不能使用CompositeItemWriter,因为我试图将一个对象转换为两个不同的对象。ClassifierCompositeItemWriter的工作原理类似于路由器,它沿着特定于某个条件的路径发送,这不是我想要做的。
作为参考,我尝试过用Spring集成做类似的事情,但也遇到了类似的障碍。
感谢您的帮助。
也许我的答案是你的例外。我也看到了同样的问题,我使用了classifierCompositeWriter
来解决它。我在我的项目中定义了分类器,正如你所见,你可以决定在逻辑中使用哪个编写器。例如,在我的逻辑中
if(baseEntity instanceof Product){
return productItemWriter;
}else {
return otherItemWriter;
}
祝你好运。
你可以用chain写多个表,
<int:chain input-channel="processTransactionChannel"
output-channel="processedItems">
<int:header-enricher>
<int:header name="savePayload" expression="payload" />
</int:header-enricher>
<int-jpa:updating-outbound-gateway
auto-startup="true"
native-query="insert into TableOne values( :transactionStatus ,bank_Reference_Number = :bankReferenceNumber )"
entity-manager="entityManager"
use-payload-as-parameter-source="false">
<int-jpa:transactional />
<int-jpa:parameter name="transactionStatus"
expression="payload['transactionStatus']" />
<int-jpa:parameter name="bankReferenceNumber"
expression="payload['bankReferenceNumber']" />
</int-jpa:updating-outbound-gateway>
<int:transformer expression="headers.savePayload" />
<int-jpa:updating-outbound-gateway
native-query="insert
into PARTNER_RESPONSE_DETAILS(PARTNER_ID,BANK_REFERENCE_NUMBER,REQUEST_STRING,RESPONSE_STRING)
values (:partnerId,:bankRefNumber,:requestString,:responseString)"
entity-manager="entityManager">
<int-jpa:transactional />
<int-jpa:parameter name="partnerId" expression="payload['partnerId']" />
<int-jpa:parameter name="bankRefNumber" expression="payload['bankRefNumber']" />
<int-jpa:parameter name="requestString" expression="payload['requestString']" />
<int-jpa:parameter name="responseString"
expression="payload['responseString']" />
<int-jpa:parameter name="transactionStatus"
expression="payload['transactionStatus']" />
<int-jpa:parameter name="bankReferenceNumber"
expression="payload['bankReferenceNumber']" />
</int-jpa:updating-outbound-gateway>
<int:transformer expression="headers.savePayload" />
</int:chain>
我相信@Hansjoerg和@Luca的评论对这个问题提供了有价值的回答,并在研究之前和期间进行了研究以寻找答案。
我通过继续使用ItemSqlParameterSourceProvider解决了这个问题,代码如下。当我最初探索如何使用这个类及其方法时,我的想法是,我仍然只在ClaimLine类上操作。
真正发生的情况是,方法从编写器接收类,并且您正在设置用setSQL(String sql)设置的SQL语句的值。使用ItemSqlParameterSourceProvider,您将使用SQL中的命名参数来表示put语句。下面的代码仅显示声明的代码。药房将类似。
public class ClaimItemSqlParameterSourceProvider implements ItemSqlParameterSourceProvider<ClaimLine> {
@SuppressWarnings({ "serial"})
@Override
public SqlParameterSource createSqlParameterSource(final ClaimLine item) {
return new MapSqlParameterSource(new HashMap<String, Object>() {
{
put("rxclaimid", item.getRxClaimID());
...
// many more
}
});
}
}
自定义条目编写器可能也解决了这个问题,但似乎需要更多的编码来支持它。最后,对于这种情况,使用ItemPreparedStatementSetter或ItemSqlParameterSourceProvider都可以。我们选择后者的主要原因是,参数的名称是明确的,而不是通过索引值(1、2、3等)和使用“?”来访问参数值在setSQL调用中。
我正在尝试在没有项目编写器的情况下使用下面的配置来配置spring批处理步骤。然而,我错误地说writer元素既没有'writer'属性,也没有元素。 我浏览了链接spring批处理:没有ItemWriter的Tasklet。但无法解决问题。有人能告诉我在我提到的代码片段中要做的具体更改吗
CompositeItemWriter:当我需要将项目平均地分给Writer时,似乎会将所有读取的项目传递给所有的Writer。 BacktoBackPatternClassifier:我并不真正需要分类器,因为我是均匀地拆分项目。 有没有另一种方式,让一个读者和多个作者? 或者我可以在Writer中手动创建线程?
我刚开始使用Spring批处理,我有一个特殊问题。我希望使用从3个不同的jpa查询中获取结果,并分别处理它们,然后使用将它们写入一个统一的XML文件。 对于eg,生成的XML看起来像是,
我有从多个文件读取并写入多个文件的Spring批处理配置。是否可以只写入从多个读取的一个文件。假设我收到巨大的XML文件,我将XML拆分为小文件并使用分区器并行读取小文件。但我需要将从不同的小xml文件读取的所有数据写入一个输出文件。Spring批处理是否可以做到这一点?我知道通过使写入器同步是可能的,但我正在寻找任何其他可能的方式作业配置 我得到错误组织。springframework。一批项目
我需要从多个目录中读取文件,并处理数据并将其存储到DB中。目前我正在使用块多资源阅读器,它适用于1个目录。但现在我必须从多个目录中读取文件。如何使用Spring批处理来做到这一点
矩阵示例是: 它通过以下方式保存到文件中 write.table (Aexample,file = "~/R/Aexample ",row.names = FALSE,col . names = FALSE); 然后我读到 Aexample=as.matrix(read.table(file="~/R/Aexample")); 但是结果总是有我不想要的V1 V2 V3 V4列名: 保存Aexamp