Spring batch 如何使ItemReader读取2个表

Spring batch 如何使ItemReader读取2个表,spring-batch,Spring Batch,我必须创建一个批处理作业来进行财务对账。现在我有3个步骤: 步骤1:从第三方读取XML,在我们的domains对象中转换,在DB中写入(表1) 步骤2:从我们的事务数据存储中读取一个平面文件,在DB中写入(表2) 步骤3:读取aggregatorObject中的表1和表2,处理这两个列表以查找差异并设置状态代码,在表2中编写状态代码 我的问题是第三步。我找不到一个好的解决方案让我的ItemReader从2SQL中读取 我从这样一个自定义ItemReader开始: package batch.co

我必须创建一个批处理作业来进行财务对账。现在我有3个步骤:

步骤1:从第三方读取XML,在我们的domains对象中转换,在DB中写入(表1)

步骤2:从我们的事务数据存储中读取一个平面文件,在DB中写入(表2)

步骤3:读取aggregatorObject中的表1和表2,处理这两个列表以查找差异并设置状态代码,在表2中编写状态代码

我的问题是第三步。我找不到一个好的解决方案让我的ItemReader从2SQL中读取

我从这样一个自定义ItemReader开始:

package batch.concilliation.readers;


@Component("conciliationReader")
public class TransactionReader implements ItemReader<TransactionsAgragegator>{

private final Logger log = Logger.getLogger(TransactionReader.class);

@Autowired
private ConciliationContext context;

@Autowired
private ServiceSommaireConciliation serviceTransactionThem;

@Autowired
private ServiceTransactionVirement serviceTransactionUs;


@Override
public TransactionsAgragegator read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {

    TransactionsAgragegator agregator = new TransactionsAgragegator();

    SommaireConciliationVirementInterac sommaire = serviceSommaireThem.findByRunNo(context.getRunNo());

    List<TransactionVirement> journalSic = serviceTransactionUs.findByTimestamp(sommaire.getBeginDate(), sommaire.getEndDate()); 

    // on place ces deux listes dans l'objet agregteur.
    agregator.setListeTransactionThem(sommaire.getPayments());
    agregator.setListeTransactionsUs(journalSic);

    return aggregator;
}

}
package batch.concilliation.readers;
@组成部分(“调解阅读器”)
公共类TransactionReader实现ItemReader{
私有最终记录器log=Logger.getLogger(TransactionReader.class);
@自动连线
私人调解语境;
@自动连线
私人服务主要是对账服务交易;
@自动连线
私人服务交易virement serviceTransactionUs;
@凌驾
public TransactionAgrageGator read()引发异常、UnexpectedInputException、ParseException、NontTransientResourceException{
TransactionAgrageGator agregator=新TransactionAgrageGator();
sommaiconreconciliationvirementinterac sommaire=serviceSommaireThem.findbyruno(context.getRunNo());
List journalSic=serviceTransactionUs.findByTimestamp(sommaire.getBeginDate(),sommaire.getEndDate());
//在双人广场上,他坐的是一辆汽车。
agregator.setListTransactionThem(sommaire.getPayments());
agregator.setlistedtransactionsus(日志);
返回聚合器;
}
}
此读取器使用两个已实现的服务(DAO),它们同时读取表和返回域对象。我从我们和他们那里获取两个事务列表,并将它们放在聚合器对象中。这个对象将被传递到ItemProcessor,我可以执行我的业务逻辑。。。但是这个读卡器会启动一个无限循环,因为它永远不会读取null

我读过关于ItemReaderAdapter的文章,但是我仍然有同样的问题,就是在集合上循环,直到得到null

总之,我想阅读两个不同的表格,得到两个列表:

List<TransactionThirdParty>
List<TransactionHome>
列表
列表
然后我的ItemProcessor会检查两个列表是否相等,一个列表的事务数是否比另一个多,等等


任何春季批量专家都能提出一些建议吗

这里的问题是,前两个步骤是面向块的,但第三个步骤不是。虽然前两个步骤可能具有通常的读处理-写循环,但依赖于前两个步骤的第三个步骤是一次性操作。它与在批处理域中复制文件没有什么不同

因此,您不应该在这里使用ItemReader,因为您没有退出条件(这就是为什么您从未从读取器获得null,因为它不处理行或记录,所以它无法知道源何时耗尽)

这是有帮助的地方

Tasklet是一个简单的接口,它有一个方法execute,它 将由TaskletStep重复调用,直到返回 RepeatStatus.FINISHED或引发异常以表示失败


因此,将第三步作为一种而不是面向块的方式来实施。

谢谢。我将对此进行研究。如果我理解的话,也是如此。我应该在一个tasklet中完成我的阅读(调用我的2个dao方法)、处理和写操作?我没有数百万条记录,但我可能会在50k范围内。我不确定这一点,因为你写了“我的ItemProcessor会检查两个列表是否相等,一个列表有多少尝试,然后另一个..等等”我看不出其他方法。如果您的业务逻辑要求您比较两个DAO的结果,tasklet是一种方法。但是如果我误解了上述行,您需要一个记录一个记录的比较(而不是它们的列表),那么您就不应该使用这些dao函数了。谢谢您的回答。我将最终重新设计我的步骤来避免这种情况。