2

当我通过引用 mybatis 映射器的 DAO 插入数据时,会影响多个表。

public void insertStuff(Collection<Stuff> data) {
   for (Stuff item : data) {
      mapper.insertT1(item.getT1Stuff());
      mapper.insertT2(item.getT2Stuff());
      Collection<MainStuff> mainData = item.getMainStuff();
      for (MainStuff mainItem : mainData) {
         mapper.insertMainData(mainItem);
      }
   }
}

我正在使用 mybatis 的 BATCH 执行器类型,但我很快就达到了 Oracle 的 MAX_CURSOR 限制,因为在通过主循环的每次迭代中为三个映射器语句中的每一个创建了一个新的 PreparedStatement(和一个新的连接)。我可以通过循环多次迭代来避免这种情况:

public void insertStuff(Collection<Stuff> data) {
   for (Stuff item : data) {
      mapper.insertT1(item.getT1Stuff());
   }
   for (Stuff item : data) {
      mapper.insertT2(item.getT2Stuff());
   }
   for (Stuff item : data) {
      Collection<MainStuff> mainData = item.getMainStuff();
      for (MainStuff mainItem : mainData) {
         mapper.insertMainData(mainItem);
      }
   }
}

然而,后一种代码的可读性较差,在性能方面有点成本,并且破坏了模块化。

有一个更好的方法吗?是否需要直接使用 SqlSession 并在一定数量排队后刷新语句?

4

1 回答 1

3

如果要使用批处理,则应使用第二种方式。在第一个代码中,您实际上没有任何批次。真正的批次有 N 个相同的语句。如果您执行了 3 个不同的查询并将它们封装成批处理,那么您的 jdbc 驱动程序会将它们分成 3 个批处理,一个查询。在第二个代码中,如果您有大量数据,将有三个批次,这是最快的。

于 2013-01-03T17:38:03.877 回答