You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法将百万条CSV记录插入MySQL数据库,寻求批量处理及每百行打印的代码实现方案

解决百万条CSV插入MySQL失败+每100行打印的问题

我来帮你搞定这两个问题,咱们先拆解需求再调整代码:

一、实现每读取100行就打印的功能

这个很简单,你只需要在读取CSV记录的循环里加一个计数器,每次循环后判断计数器是否是100的倍数就行。具体位置就在遍历CSVRecord的那个for循环里,看下面的代码示例就能明白。

二、解决百万条数据插入失败的问题

你现在的代码是把所有百万条数据先塞进ArrayList,再一次性批量插入,这会导致两个核心问题:

  • 内存溢出:百万条对象存在List里,内存占用会非常大,直接撑爆JVM
  • MySQL批量插入限制:MySQL的max_allowed_packet和JDBC批处理的缓冲区都有上限,一次性提交太多数据会被数据库拒绝

解决办法是分批提交:比如每读取1000条就执行一次批处理并提交,同时清空批处理缓冲区,避免内存占用过高。另外还要用try-with-resources自动管理资源(比如BufferedReader、Connection、PreparedStatement),避免资源泄漏。

优化后的完整代码

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;

import java.io.BufferedReader;
import java.io.FileReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class CsvToMysql {
    private static final int BATCH_SIZE = 1000; // 每1000条提交一次,可根据机器性能调整
    private static final int PRINT_INTERVAL = 100; // 每100行打印一次进度

    public static void main(String[] args) {
        String csvFilePath = "C:\\Student1.csv";
        
        // 使用try-with-resources自动关闭资源,避免手动关闭遗漏导致泄漏
        try (BufferedReader lineReader = new BufferedReader(new FileReader(csvFilePath));
             CSVParser records = CSVParser.parse(lineReader, CSVFormat.EXCEL.withFirstRecordAsHeader().withIgnoreHeaderCase().withTrim());
             Connection con = dbconnection();
             PreparedStatement statement = con.prepareStatement("INSERT INTO test12(DOB, NAME, GENDER) VALUES (?, ?, ?)")) {

            int rowCount = 0;
            for (CSVRecord record : records) {
                rowCount++;
                
                // 每读取100行打印一次进度
                if (rowCount % PRINT_INTERVAL == 0) {
                    System.out.println("已读取并处理 " + rowCount + " 行数据");
                }

                // 给预编译语句设置参数
                statement.setString(1, record.get(0));
                statement.setString(2, record.get(1));
                statement.setString(3, record.get(2));
                statement.addBatch();

                // 每积累到BATCH_SIZE条,执行批处理并提交事务
                if (rowCount % BATCH_SIZE == 0) {
                    statement.executeBatch();
                    con.commit();
                    statement.clearBatch(); // 清空批处理缓冲区,避免内存堆积
                    System.out.println("已成功插入 " + rowCount + " 条数据");
                }
            }

            // 处理最后一批不足BATCH_SIZE的数据
            if (rowCount % BATCH_SIZE != 0) {
                statement.executeBatch();
                con.commit();
                System.out.println("已成功插入最后一批数据,总计 " + rowCount + " 条");
            }

        } catch (SQLException ex) {
            ex.printStackTrace();
            // 出现异常时回滚事务,避免部分插入导致数据不一致
            try (Connection con = dbconnection()) {
                if (con != null) {
                    con.rollback();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public static Connection dbconnection() {
        Connection connection = null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/newschema1", "root", "12345");
            connection.setAutoCommit(false); // 关闭自动提交,手动控制事务
            System.out.println("数据库连接成功");
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        }
        return connection;
    }
}

关键优化点说明

  • 每100行打印:在遍历CSV记录的循环中加入rowCount计数器,当rowCount % PRINT_INTERVAL == 0时打印当前处理进度
  • 分批提交:设置BATCH_SIZE(可根据机器性能调整),每积累到这个数量就执行executeBatch()并commit(),同时清空批处理缓冲区
  • 资源自动管理:用try-with-resources包裹所有需要关闭的资源,不用手动调用close(),避免资源泄漏
  • 异常回滚:当SQL异常发生时,回滚事务,避免部分插入导致数据不一致

内容的提问来源于stack exchange,提问作者user10025328

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 08:37:27