使用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
相关产品推荐
相关产品推荐

