繁体   English   中英

如何在春季批处理中使用itemWriter编写子记录

[英]How to write child record using itemWriter in spring batch

我的情况:

我有我从readerItem中的db读取的类A。 然后,我需要处理此类A,并创建我在itemProcessor中执行的类别B。 最后,我将B类保存到itemWriter中的db中。

问题:在处理中,我还需要创建具有B类外键的C类(大约100万条记录),并保存该C类。我该怎么做。

我不能做这样的事情:因为我写的时候有大约100万条记录,我应该在内存中存储大约2gb的空间。 所以我应该如何解决这个问题。

public class BWriter extends BaseItemWriter<B> {

    public void write(List<? extends B> data) throws Exception {
        logger.info("Start writing: " + data);
        for (B item : data) {
            myCustomDao.saveB(item);
            for (C itemC : item.getC()) {
                itemC.setB(item);
                myCustomDao.saveC(itemC);
            }
        }
    }
}

更新:

可能的解决方案,其中不包括我想要的春季批处理:

    List<C> cList = new ArrayList<C>();
    int i = 0;
    String line;
    while ((line = reader.readLine()) != null) {
        String[] data = line.split(";");
        if (data.length > 1 && !StringUtils.isBlank(data[1])) {
            C cItem = new C();
            cItem.set(...);
            cList.add(i, cItem);
            if (++i >= 1000) {
                myCustomDao.save(cList);
                cList = new ArrayList<C>();
                i = 0;
            }
        }
    }
  if (!cList.isEmpty())
                myCustomDao.save(cList);

如果由于一个B元素最多可以包含100万个C对象而无法将commit-interval减小到一个很小的值,则可以这样做:

将类A转换为类B,而不在已处理的B对象中创建C对象;
在您的BWriter附加一个ItemWriteListener<B>.afterWrite() ,在其中创建/保存C对象(与在侦听器中接收到的List<B>有关),从而使您的内存消耗降低,但是您可以保证在其中工作交易边界。

如果问题是由于使用Hibernate而不是纯JDBC而引起的,则可以考虑手动使用无状态会话或flush()/clear()会话。 数据库的1mil记录不是很大
不幸的是,当您有大量数据时,ORM不是最佳选择。

我的2美分,与您一样,对于Spring-batch来说还是很新的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM