Java 大量データを登録/更新する(addBatch)

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)

△上に戻る