寻求支持多数据库的JDBC命令行导出SQL结果到CSV工具
跨数据库JDBC CSV导出工具方案
一、现成工具推荐
其实有不少现成工具能直接满足你的需求,不用从零开始写代码:
- CSVExport:轻量级Java工具,专门做JDBC到CSV的导出,支持你需要的参数格式,适配多数据库
- DBVisualizer:虽然是GUI工具,但自带命令行模式,支持多数据库导出CSV,不过免费版有功能限制
- Sqoop:更偏向大数据场景,但也支持通过JDBC将数据导出到本地CSV,只是配置稍复杂
不过如果你需要完全贴合你指定调用格式的自定义工具,下面是一套完整的实现方案,包含代码和打包步骤,我会尽量写得通俗易懂。
二、自定义Java工具实现
1. 核心代码(ExportToCSV.java)
我写了最简化的代码,覆盖所有你需要的参数,还处理了CSV的格式规范(比如分号分隔、特殊字符转义):
import java.io.FileWriter; import java.io.IOException; import java.sql.*; import java.util.ArrayList; import java.util.List; public class ExportToCSV { public static void main(String[] args) { // 检查参数数量是否符合要求 if (args.length != 7) { System.err.println("用法: java -jar ExportToCSV.jar <jdbc-URL> <driver location> <driver class> <login> <pwd> <query> <output file>"); System.exit(1); } // 解析传入的参数 String jdbcUrl = args[0]; String driverPath = args[1]; String driverClass = args[2]; String login = args[3]; String password = args[4]; String query = args[5]; String outputFile = args[6]; // 从指定路径加载JDBC驱动 try { ClassLoader driverLoader = new java.net.URLClassLoader( new java.net.URL[]{new java.io.File(driverPath).toURI().toURL()} ); Class.forName(driverClass, true, driverLoader); } catch (Exception e) { System.err.println("驱动加载失败: " + e.getMessage()); e.printStackTrace(); System.exit(1); } // 初始化数据库连接和文件写入资源 Connection conn = null; Statement stmt = null; ResultSet rs = null; FileWriter writer = null; try { // 建立数据库连接 conn = DriverManager.getConnection(jdbcUrl, login, password); stmt = conn.createStatement(); rs = stmt.executeQuery(query); // 获取查询结果的列名,用于生成CSV表头 ResultSetMetaData metaData = rs.getMetaData(); int columnCount = metaData.getColumnCount(); List<String> columnNames = new ArrayList<>(); for (int i = 1; i <= columnCount; i++) { columnNames.add(metaData.getColumnName(i)); } // 写入CSV文件 writer = new FileWriter(outputFile); // 写入表头行 writer.write(String.join(";", columnNames) + "\n"); // 逐行写入数据 while (rs.next()) { List<String> rowData = new ArrayList<>(); for (int i = 1; i <= columnCount; i++) { Object value = rs.getObject(i); // 处理空值和特殊字符(分号、换行符转义) String strValue = value == null ? "" : value.toString().replace(";", "\\;").replace("\n", "\\n"); rowData.add(strValue); } writer.write(String.join(";", rowData) + "\n"); } System.out.println("数据已成功导出到: " + outputFile); } catch (SQLException e) { System.err.println("数据库操作出错: " + e.getMessage()); e.printStackTrace(); System.exit(1); } catch (IOException e) { System.err.println("写入文件出错: " + e.getMessage()); e.printStackTrace(); System.exit(1); } finally { // 关闭所有资源,避免内存泄漏 try { if (rs != null) rs.close(); } catch (SQLException e) {} try { if (stmt != null) stmt.close(); } catch (SQLException e) {} try { if (conn != null) conn.close(); } catch (SQLException e) {} try { if (writer != null) writer.close(); } catch (IOException e) {} } } }
2. 打包成可执行Jar的步骤
因为你不熟悉Java,我会一步步说明操作:
前提准备
- 安装JDK 8或更高版本,确保
javac(编译命令)和jar(打包命令)能在命令行直接调用
步骤1:编译代码
把上面的代码保存为ExportToCSV.java,打开命令行进入文件所在目录,执行:
javac ExportToCSV.java
执行后会生成ExportToCSV.class字节码文件。
步骤2:创建Manifest配置文件
新建一个名为manifest.mf的文本文件,内容如下:
Main-Class: ExportToCSV Class-Path: .
⚠️ 注意:文件最后必须留一行空行,否则打包会失败。
步骤3:打包成可执行Jar
在命令行执行:
jar cvfm ExportToCSV.jar manifest.mf ExportToCSV.class
执行完成后,你会得到ExportToCSV.jar这个可执行包。
三、工具使用示例
完全按照你要求的格式调用,比如Sybase的例子:
java -jar ExportToCSV.jar 'jdbc:sybase:db.com:11/sys' 'path/to/JDBCsybaseDriver.jar' 'com.sybase.jdbc3.jdbc.SybDriver' 'root' '' 'SELECT * FROM <tab> WHERE <cond>' 'output.csv'
- 如果你的查询语句包含空格或特殊字符,记得用引号包裹(Windows系统建议用双引号,Linux/macOS用单引号)
- 空密码直接传空字符串即可,比如例子中的
''
四、注意事项
- 确保JDBC驱动Jar的路径正确,绝对路径或相对路径都可以
- 不同数据库的JDBC URL格式要对应正确:比如Oracle是
jdbc:oracle:thin:@//host:port/service,MySQL是jdbc:mysql://host:port/dbname - 如果需要处理更多特殊字符(比如引号),可以修改代码中
strValue的转义逻辑
内容的提问来源于stack exchange,提问作者Philippe




