1. 程式人生 > 實用技巧 >【JDBC核心】批量插入

【JDBC核心】批量插入

批量插入

批量執行 SQL 語句

當需要成批插入或者更新記錄時,可以採用 Java 的批量更新機制,這一機制允許多條語句一次性提交給資料庫批量處理。通常情況下比單獨提交處理更有效率。

JDBC 的批量處理語句包括下面三個方法:

  • addBatch(String):新增需要批量處理的 SQL 語句或是引數;
  • executeBatch():執行批量處理語句;
  • clearBatch():清空快取的資料。

通常會遇到兩種批量執行 SQL 語句的情況:

  • 多條 SQL 語句的批量處理;
  • 一個 SQL 語句的批量傳參。

高效的批量插入

package cn.parzulpan.jdbc.ch05;

import cn.parzulpan.jdbc.util.JDBCUtils;
import org.junit.Test;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.Statement;

/**
 * @Author : parzulpan
 * @Time : 2020-12-01
 * @Desc : 批量插入
 */

public class BulkInsertTest {

    // 實現方式一:使用 Statement
    @Test
    public void test1() throws Exception {
        long start = System.currentTimeMillis();

        Connection connection = JDBCUtils.getConnection();
        Statement statement = connection.createStatement();
        for (int i = 0; i < 1000; i++) {
            String sql = "insert into goods(name)values('name_" + i + "')";
            statement.executeUpdate(sql);
        }

        JDBCUtils.closeResource(connection, statement);

        long end = System.currentTimeMillis();
        System.out.println(end - start);    // 1000 -> 131751ms
    }

    // 實現方式二:使用 PrepareStatement
    @Test
    public void test2() throws Exception {
        long start = System.currentTimeMillis();

        Connection connection = JDBCUtils.getConnection();
        String sql = "insert into goods(name)values(?)";
        PreparedStatement statement = connection.prepareStatement(sql);
        for (int i = 0; i < 1000; i++) {
            statement.setString(1, "name_" + i);
            statement.executeUpdate();
        }

        JDBCUtils.closeResource(connection, statement);

        long end = System.currentTimeMillis();
        System.out.println(end - start);    // 1000 -> 122340ms
    }

    // 實現方式三:使用 批量處理語句
    // mysql 伺服器預設是關閉批處理的,需要通過一個引數,讓 mysql 開啟批處理的支援。
    // ?rewriteBatchedStatements=true 寫在配置檔案的 url 後面
    @Test
    public void test3() throws Exception {
        long start = System.currentTimeMillis();

        Connection connection = JDBCUtils.getConnection();
        String sql = "insert into goods(name)values(?)";
        PreparedStatement statement = connection.prepareStatement(sql);
        for (int i = 0; i < 1000; i++) {
            statement.setString(1, "name_" + i);

            // 1. "攢" sql
            statement.addBatch();
            if (i % 500 == 0) {
                // 2. 執行
                statement.executeBatch();
                // 3. 清空
                statement.clearBatch();
            }
        }

        JDBCUtils.closeResource(connection, statement);

        long end = System.currentTimeMillis();
        System.out.println(end - start);    // 1000 -> 69084ms
    }

    // 實現方式四:設定為不自動提交資料
    @Test
    public void test4() throws Exception {
        long start = System.currentTimeMillis();

        Connection connection = JDBCUtils.getConnection();

        // 1. 設定為不自動提交資料
        connection.setAutoCommit(false);
        String sql = "insert into goods(name)values(?)";
        PreparedStatement statement = connection.prepareStatement(sql);
        for (int i = 0; i < 1000; i++) {
            statement.setString(1, "name_" + i);

            // 1. "攢" sql
            statement.addBatch();
            if (i % 500 == 0) {
                // 2. 執行
                statement.executeBatch();
                // 3. 清空
                statement.clearBatch();
            }
        }

        // 2. 提交資料
        connection.commit();

        JDBCUtils.closeResource(connection, statement);

        long end = System.currentTimeMillis();
        System.out.println(end - start);    // 1000 -> 1338ms

    }
}

推薦使用方式四。

練習和總結