0

我的情况:

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

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

我不能做这样的事情:因为在我写的时候,我有大约 1 百万条记录,我需要在内存中存储大约 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);
4

1 回答 1

0

commit-interval如果因为一个 B 元素最多可以有 100 万个 C 对象而减少到一个小值而不是一个选项,那么您可以这样做:

将 A 类处理到 B 类,而不在已处理的 B 对象中创建 C 对象;
在您BWriter附加一个ItemWriteListener<B>.afterWrite()您创建/保存 C 对象(与List<B>在侦听器中接收相关)的地方,因此您的内存消耗很低,但您可以保证在事务边界中工作。

如果问题是由于使用 Hibernate 而不是普通 JDBC 造成的,您可以考虑flush()/clear()手动使用无状态会话或会话;数据库的 100 万条记录并不是一个大数字
不幸的是,当您拥有大量数据时,ORM 不是最佳选择。

我的 2 美分,我对 Spring-batch 很陌生。

于 2013-08-27T11:52:18.413 回答