Javaで大量データを登録/更新するサンプルです。MySQLに接続します。(確認環境:Java8)
目次
サンプル | バッチ更新(addBatch) |
Statementでのバッチ更新 | |
Statementでループで登録 | |
PreparedStatementでのバッチ更新 |
バッチ更新(addBatch)
- 複数のSQL文をまとめてDBに登録/更新します。
- SQL文を 1 つずつ送るよりパフォーマンスが向上します。
- バッチ更新は、StatementまたはPreparedStatementまたはCallableStatementのオブジェクトを使用できます。
- 以下は、Oracleのバッチ更新のページのリンクです。
https://docs.oracle.com/javase/jp/1.3/guide/jdbc/spec2/jdbc2.1.frame6.html
Statementでのバッチ更新
package test1;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class Test1 {
public static void main(String[] args) {
String url
= "jdbc:mysql://localhost:3309/testdb";
String user = "root";
String pass = "";
String SQL1
= "insert into employee (id,name,romaji) VALUES (1,'鈴木','suzuki')";
String SQL2
= "insert into employee (id,name,romaji) VALUES (2,'田中','tanaka')";
String SQL3
= "update employee set name = 'テストネーム'";
try(Connection conn =
DriverManager.getConnection(url, user, pass)){
conn.setAutoCommit(false);
try(Statement stmt = conn.createStatement()){
stmt.addBatch(SQL1);
stmt.addBatch(SQL2);
stmt.addBatch(SQL3);
int[] cnt = stmt.executeBatch();
conn.commit();
for (int i: cnt){
System.out.println
("SQLの更新件数は、"+ i + "件です");
}
} catch (Exception e) {
conn.rollback();
System.out.println("rollback");
throw e;
}
} catch (Exception e) {
e.printStackTrace();
}finally {
System.out.println("処理が完了しました");
}
}
}
24行目は、createStatementメソッドでStatementオブジェクトを生成しています。
25-27行目は、addBatchメソッドでバッチ登録しています。
29行目は、executeBatchメソッドで実行処理をしています。executeBatchメソッドの戻り値は、更新カウントの配列を返します。配列の1つの要素は1つのSQLで何件更新したかを表します。
サンプルでは以下のように出力されます。
SQLの更新件数は、1件です
SQLの更新件数は、1件です
SQLの更新件数は、2件です
処理が完了しました。
17,18,22行目は、try-with-resources構文です。リソースを自動でクローズします。
mysqlへの接続はドライバが必要です。
https://itsakura.com/java-mysql#s8
Statementでループで登録
package test1;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
public class Test1 {
public static void main(String[] args) {
String url
= "jdbc:mysql://localhost:3309/testdb";
String user = "root";
String pass = "";
String SQL1
= "insert into employee (id,name,romaji) VALUES (";
List<String> SQL = new ArrayList<>();
String[] name = {"鈴木","田中","佐藤"};
String[] romaji = {"suzuki","tanaka","sato"};
int number1 = 0;
// 複数のinsert文を生成
for (int i = 0; i < name.length; i++) {
number1 = number1 + 1;
SQL.add(SQL1 + number1 + ",'" + name[i] + "','" + romaji[i] + "');");
}
try(Connection conn =
DriverManager.getConnection(url, user, pass)){
conn.setAutoCommit(false);
try(Statement stmt = conn.createStatement()){
// 複数のinsert文を登録
for (int i = 0; i < SQL.size(); i++) {
stmt.addBatch(SQL.get(i));
}
int[] cnt = stmt.executeBatch();
conn.commit();
for (int i: cnt){
System.out.println
("SQLの更新件数は、"+ i + "件です");
}
} catch (Exception e) {
conn.rollback();
System.out.println("rollback");
throw e;
}
} catch (Exception e) {
e.printStackTrace();
}finally {
System.out.println("end");
}
}
}
23行目は、19行目の配列の要素数分ループでinsert文を作成しリストに追加しています。
35行目からリストの要素分更新しています。
PreparedStatementでのバッチ更新
package test1;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
public class Test1 {
public static void main(String[] args) {
String url
= "jdbc:mysql://localhost:3309/testdb";
String user = "root";
String pass = "";
String SQL1 = "insert into employee (id,name) VALUES (?,?)";
// String SQL1 = "update employee set name = ? where id = ?";
try(Connection conn =
DriverManager.getConnection(url, user, pass)){
conn.setAutoCommit(false);
try(PreparedStatement ps = conn.prepareStatement(SQL1)){
ps.setInt(1,1);
ps.setString(2,"suzuki");
ps.addBatch();
ps.setInt(1,2);
ps.setString(2,"tanaka");
ps.addBatch();
// ps.setString(1,"テストネーム");
// ps.setInt(2,1);
// ps.addBatch();
int[] cnt = ps.executeBatch();
conn.commit();
for (int i: cnt){
System.out.println
("SQLの更新件数は、"+ i + "件です");
}
} catch (Exception e) {
conn.rollback();
System.out.println("rollback");
throw e;
}
} catch (Exception e) {
e.printStackTrace();
}finally {
System.out.println("処理が完了しました");
}
}
}
13行目は、SQL文です。値の箇所はプレースホルダ(?)になっています。
21行目は、prepareStatementメソッドでPreparedStatementオブジェクトを生成してます。
22行目からは、プレースホルダに値をセットしています。1つめの引数はプレースホルダの位置です。2つめの引数は値です。
24,28行目は、addBatchメソッドでバッチ登録しています。
34行目は、executeBatchメソッドで実行処理をしています。executeBatchメソッドの戻り値は、更新カウントの配列を返します。配列の1つの要素は1つのSQLで何件更新したかを表します。
コメントの14,30-32行目はupdate文です。insert文をコメントにしupdateのコメントを外すとupdateを実行できます。
サンプルでは以下のように出力されます。
SQLの更新件数は、1件です
SQLの更新件数は、1件です
処理が完了しました
16,21行目は、try-with-resources構文です。リソースを自動でクローズします。
以下はJava8 API仕様のStatementインターフェースのリンクです。
https://docs.oracle.com/javase/jp/8/docs/api/java/sql/Statement.html
以下はJava8 API仕様のPreparedStatementインターフェースのリンクです。https://docs.oracle.com/javase/jp/8/docs/api/java/sql/PreparedStatement.html
関連の記事
Java MySQLに接続してselectするサンプル
Java MySQLでデータ更新する(insert/update/delete)