## モジュール 3: プリペアドステートメントとバッチ挿入の使用

プリペアドステートメントを使用すると、繰り返し実行するためのステートメントを事前にコンパイルできます。プリペアドステートメントはSQLインジェクションを防ぐのに役立ちます。さらに、クエリが長く複雑で、ネットワークがボトルネックになっている場合、プリペアドステートメントはクエリ実行パフォーマンスを向上させる可能性があります。

バッチ挿入により、ユーザーは単一のSQLステートメントで複数行のデータを挿入できます。

このモジュールでは、プリペアドステートメントとバッチ挿入の例を見ていきます。

### 手順 1. プリペアドステートメントの使用

+ 左側のVS Codeの**EXPLORER**セクションで、`DemoJdbcPreparedStatement.java`ファイルをクリックし、コードファイルを読んでください。

+ プリペアドステートメントの使用には2つの方法があります。以下の最初のコードスニペットはサーバーサイドのプリペアドステートメントを示しています。2番目のコードブロックはクライアントサイドのプリペアドステートメントを示しています。この例では、実行時間が類似していることがわかります。

  ```java
  // Reuse PS
  connection.setAutoCommit(true);
  PreparedStatement update1_ps = connection.prepareStatement("UPDATE test.t1 SET name = ? WHERE id = 1");
  System.out.println(">>> Reuse PS Begin repeating update.");
  long s1 = System.currentTimeMillis();
  for (int i = 0; i < 200; i++) {
      update1_ps.setString(1, Integer.toString(i));
      update1_ps.executeUpdate();
  }
  update1_ps.close();
  ```

  ```java
  /**
  * Client side caching prepared statement, cache hit for prepareStatement and close.
  * Try set cachePrepStmts=false|true to see the difference on elapsed time.
  */
  PreparedStatement update2_ps = null;
  System.out.println(">>> Non-Reuse PS Begin repeating update.");
  long s2 = System.currentTimeMillis();
  for (int i = 0; i < 200; i++) {
      update2_ps = connection.prepareStatement("UPDATE test.t1 SET name = ? WHERE id = 1");
      update2_ps.setString(1, Integer.toString(i));
      update2_ps.executeUpdate();
      update2_ps.close();
  }
  ```

+ コードを実行して結果を確認できます。

  ```bash
  rm -f DemoJdbcPreparedStatement.class
  javac -cp mysql-connector-j-9.1.0.jar DemoJdbcPreparedStatement.java
  sleep 1
  java -cp :mysql-connector-j-9.1.0.jar DemoJdbcPreparedStatement
  ```

  ```output
  Connection established.
  >>> Reuse PS Begin repeating update.
  >>> End repeating update, elapsed: 4364(ms).
  >>> Non-Reuse PS Begin repeating update.
  >>> End repeating update, elapsed: 4225(ms).

  Executing query: select * from test.t1
          Row#, id, name
          1) 1, 199
  Turn on autocommit.
  Connection closed.
  ```

### 手順 2. バッチ挿入の使用

+ 左側のVS Codeの**EXPLORER**セクションで、`DemoJdbcBatchInsert.java`ファイルをクリックします。

+ このステップでは、テーブルに1000行を挿入します。`rewriteBatchedStatements=true`と`rewriteBatchedStatements=false`の間のパフォーマンスを比較します。

  ```bash
  rm -f DemoJdbcBatchInsert.class
  javac -cp mysql-connector-j-9.1.0.jar DemoJdbcBatchInsert.java
  sleep 1
  java -cp :mysql-connector-j-9.1.0.jar DemoJdbcBatchInsert
  ```

  ```output
  Connection established.
  >>> Begin insert 1000 rows.
  >>> End batch insert,rewriteBatchedStatements=true,elapsed: 172 (ms).
  Connection established.
  >>> Begin insert 1000 rows.
  >>> End batch insert,rewriteBatchedStatements=false,elapsed: 13252 (ms).

  /* Executing query: select count(*), max(name) from test.t1_batchtest; */
          Row#, count(*), max(name)
          1) 1000, 999
  Turn on autocommit.
  Connection closed.
  ```
