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

使用OpenCSV解析CSV后,如何将数据插入SQL Server数据库?

解决OpenCSV解析后插入SQL Server的问题

看起来你已经搞定了CSV解析的核心环节,剩下的数据库插入其实就是把解析好的行数据通过JDBC和SQL Server交互的事儿,我给你梳理一套完整的实现方案,包括基础插入和批量优化:

第一步:补全OpenCSV的解析逻辑(确保数据能正确读取)

先把你截断的代码补完整,确保能稳定拿到需要的列数据:

import com.opencsv.CsvParser;
import com.opencsv.CsvParserSettings;
import javax.swing.*;
import java.io.FileReader;
import java.io.IOException;
import java.util.Arrays;

public class CsvToSql {
    public static void main(String[] args) {
        JFileChooser fileopen = new JFileChooser();
        FileNameExtensionFilter filter = new FileNameExtensionFilter("CSV file", "csv");
        fileopen.setFileFilter(filter);
        int ret = fileopen.showDialog(null, "Choose file");

        if (ret == JFileChooser.APPROVE_OPTION) {
            CsvParserSettings settings = new CsvParserSettings();
            // 跳过首行表头
            settings.setNumberOfLinesToSkip(1);
            // 选择你需要的列(索引从0开始,比如选第0、2、3列)
            settings.selectColumns(0, 2, 3);
            
            try (CsvParser parser = new CsvParser(settings);
                 // 用try-with-resources自动关闭读取流
                 FileReader reader = new FileReader(fileopen.getSelectedFile())) {
                
                String[] row;
                // 逐行解析CSV
                while ((row = parser.parseNext()) != null) {
                    // 你已经能打印这行,确认数据正确
                    System.out.println("解析到数据:" + Arrays.toString(row));
                    // 调用插入方法
                    insertDataToSqlServer(row);
                }
            } catch (IOException e) {
                System.err.println("读取CSV文件失败:" + e.getMessage());
                e.printStackTrace();
            }
        }
    }

第二步:实现SQL Server插入逻辑

1. 先确保依赖SQL Server JDBC驱动

如果用Maven,在pom.xml里加:

<dependency>
    <groupId>com.microsoft.sqlserver</groupId>
    <artifactId>mssql-jdbc</artifactId>
    <version>12.4.0.jre11</version> <!-- 根据你的Java版本选对应版本 -->
</dependency>

2. 编写插入方法

把解析到的行数据通过JDBC插入数据库,这里用PreparedStatement防止SQL注入,同时用try-with-resources自动关闭数据库资源:

private static void insertDataToSqlServer(String[] rowData) {
        // 替换成你的数据库连接信息
        String dbUrl = "jdbc:sqlserver://localhost:1433;databaseName=YourDBName;encrypt=true;trustServerCertificate=true;";
        String dbUser = "YourUsername";
        String dbPwd = "YourPassword";
        
        // 替换成你的表名和对应列名,?是参数占位符
        String insertSql = "INSERT INTO YourTableName (column1, column3, column4) VALUES (?, ?, ?)";
        
        try (
            // 自动关闭连接、PreparedStatement
            java.sql.Connection conn = java.sql.DriverManager.getConnection(dbUrl, dbUser, dbPwd);
            java.sql.PreparedStatement pstmt = conn.prepareStatement(insertSql)
        ) {
            // 给占位符赋值,注意JDBC参数索引从1开始,对应rowData的索引(从0开始)
            pstmt.setString(1, rowData[0]);
            // 如果是数字类型,要转成对应类型,比如:pstmt.setInt(2, Integer.parseInt(rowData[1]));
            pstmt.setString(2, rowData[1]);
            pstmt.setString(3, rowData[2]);
            
            // 执行插入
            int affectedRows = pstmt.executeUpdate();
            System.out.println("成功插入" + affectedRows + "行");
            
        } catch (java.sql.SQLException e) {
            System.err.println("插入数据库失败:" + e.getMessage());
            // 如果想跳过错误行继续执行,可以把异常捕获后不抛出,继续循环
            // e.printStackTrace();
        }
    }
}

第三步:优化批量插入(大数据量场景)

如果CSV数据量很大,逐行插入效率极低,改成批量插入:
修改main方法里的解析逻辑,把数据库连接和批量提交整合在一起:

if (ret == JFileChooser.APPROVE_OPTION) {
    CsvParserSettings settings = new CsvParserSettings();
    settings.setNumberOfLinesToSkip(1);
    settings.selectColumns(0, 2, 3);
    
    String dbUrl = "jdbc:sqlserver://localhost:1433;databaseName=YourDBName;encrypt=true;trustServerCertificate=true;";
    String dbUser = "YourUsername";
    String dbPwd = "YourPassword";
    String insertSql = "INSERT INTO YourTableName (column1, column3, column4) VALUES (?, ?, ?)";
    int batchSize = 100; // 每100行提交一次
    int totalCount = 0;

    try (CsvParser parser = new CsvParser(settings);
         FileReader reader = new FileReader(fileopen.getSelectedFile());
         java.sql.Connection conn = java.sql.DriverManager.getConnection(dbUrl, dbUser, dbPwd);
         java.sql.PreparedStatement pstmt = conn.prepareStatement(insertSql)) {
        
        String[] row;
        while ((row = parser.parseNext()) != null) {
            pstmt.setString(1, row[0]);
            pstmt.setString(2, row[1]);
            pstmt.setString(3, row[2]);
            pstmt.addBatch();
            totalCount++;
            
            // 达到批量大小就提交
            if (totalCount % batchSize == 0) {
                pstmt.executeBatch();
                System.out.println("已批量提交" + totalCount + "行");
            }
        }
        // 提交剩余的不足批量的行
        if (totalCount % batchSize != 0) {
            pstmt.executeBatch();
            System.out.println("最终提交剩余行,总计插入" + totalCount + "行");
        }
        
    } catch (IOException | java.sql.SQLException e) {
        System.err.println("批量插入失败:" + e.getMessage());
        e.printStackTrace();
    }
}

常见踩坑提醒

  • 数据类型匹配:如果数据库列是整数、日期等类型,不要直接用setString,要转换成对应类型,比如日期可以用LocalDateTime.parse(rowData[2])然后用pstmt.setObject(3, localDateTime)。
  • 连接字符串配置:生产环境不要用trustServerCertificate=true,要配置正确的SSL证书;如果是远程服务器,要确保1433端口开放。
  • 异常处理:如果遇到脏数据(比如格式错误),可以捕获异常后跳过当前行,避免整个程序崩溃。
  • 资源关闭:一定要用try-with-resources,确保所有流和数据库连接都能自动关闭,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:20:11