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エグゼキュータタイプを使用していますが、メインループの各反復で3つのマッパーステートメントのそれぞれに対して新しいPreparedStatement(および新しいConnection)が作成されるため、OracleのMAX_CURSOR制限にすぐに到達しています。ループを複数回繰り返すことで、これを回避できます。

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

バッチを使用する場合は、2番目の方法を使用する必要があります。最初のコードでは、実際にはバッチはありません。実際のバッチにはN個の同じステートメントがあります。3つの異なるクエリを実行し、それらをバッチにカプセル化した場合、jdbcドライバーはそれらを1つのクエリで3つのバッチに分割します。2番目のコードでは、3つのバッチがあります。これは、大量のデータがある場合に最速です。

于 2013-01-03T17:38:03.877 に答える