【问题标题】:How to make ItemReader reads 2 tables如何让 ItemReader 读取 2 个表
【发布时间】:2012-11-08 02:27:24
【问题描述】:

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

第 1 步:从第三方读取 XML,将其转换为我们的领域对象,写入 DB(表 1)

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

第3步:在aggregatorObject中同时读取table1和table2,处理两个list查找差异并设置状态码,在table2中写入状态码

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

我从这样的自定义 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;
}

}

此阅读器使用两个已实现的服务 (DAO),它们读取两个表并返回域对象。我从我们和他们那里获取两个交易列表,并将它们放在一个聚合器对象中。这个对象将被传递给 ItemProcessor,我可以做我的业务逻辑......但是这个阅读器启动了一个无限循环,因为它永远不会读取 null。

我阅读了有关 ItemReaderAdapter 的信息,但我仍然遇到同样的问题,即循环遍历一个集合,直到我得到一个 null。

总而言之,我想阅读 2 个不同的表格并获得 2 个列表:

List<TransactionThirdParty>
List<TransactionHome>

然后我的 ItemProcesssor 将检查两个列表是否相等,一个有更多或更少的交易然后另一个..etc

任何 Spring Batch 专家都可以提出建议吗?

【问题讨论】:

    标签: spring-batch


    【解决方案1】:

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

    所以你不应该在这里使用 ItemReader 方式,因为你没有退出标准(这就是为什么你永远不会从阅读器那里得到空值,它不知道源何时用尽,因为它不处理一行或记录。

    这就是TaskletStep 提供帮助的地方

    Tasklet 是一个简单的接口,它有一个方法,execute,它 将被 TaskletStep 反复调用,直到它返回 RepeatStatus.FINISHED 或抛出异常以表示失败。

    因此,将您的第三步实现为Tasklet,而不是面向块的方式。

    【讨论】:

    • 谢谢。我会调查一下。 Ttyl
    • 所以如果我明白的话。我应该在一个小任务中完成我的阅读(调用我的 2 道方法)、我的处理和我的写作吗?我没有数百万条记录,但我可能会在 50k 范围内。我不确定这个
    • 既然你写了“我的 ItemProcesssor 会检查两个列表是否相等,一个或多或少的尝试然后另一个..etc”我看不到其他方法。如果您的业务逻辑要求您比较两个 DAO 的结果,那么 tasklet 就是要走的路。但是如果我误解了上面的行并且您需要逐记录比较(而不是它们的列表),那么您不应该使用这些 dao 函数
    • 感谢您的回答。我最终会重新设计我的步骤来避免这种情况。
    猜你喜欢
    • 2015-11-13
    • 1970-01-01
    • 2021-02-12
    • 2021-10-22
    • 1970-01-01
    • 1970-01-01
    • 2020-04-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多