Gatling数据库数据导出CSV无报错但失败问题求助
问题排查与修复方案
我帮你梳理了代码里的几个核心问题,这些问题导致CSV文件没有数据写入,甚至可能引发运行时错误:
主要问题分析
- 代码执行时机错误:你把
writer.writeRow(dataString)直接写在了Simulation类的初始化代码里,而不是Gatling场景的执行流程中。Gatling的场景是声明式的,只有放在exec()这样的步骤里,代码才会在模拟运行时被执行。你当前的写法下,这行代码在场景还没运行就执行了,此时dataString是空的,自然写不出内容。 - 未初始化的变量:你注释掉了
recordCount的赋值,但后面还在用它创建数组var mList = new Array[String](recordCount),这会直接导致编译或运行时异常,因为recordCount没有有效值。 - 错误的Feeder使用方式:
jdbcFeeder是用来给负载测试的虚拟用户提供数据的,不是用来批量读取数据库数据导出的。用它来做导出会绕弯路,而且你没有在场景里处理每一行feeder数据,根本没机会收集到要写入的数据。 - 重复的资源创建:代码里创建了两次
CSVWriter,还混合使用了FileWriter,这会导致文件资源冲突,甚至无法正确写入。 - JDBC URL格式错误:URL里的
&是HTML实体转义,在Scala字符串里应该直接用&,否则会导致数据库连接失败。
修复后的代码
下面是调整后的代码,直接用JDBC API完成数据导出(更适合批量导出的场景),不需要依赖Gatling的feeder机制:
import java.io.File import com.github.tototoshi.csv._ import java.sql.DriverManager class GenerateData extends Simulation { // 配置数据库连接参数 val jdbcUrl = "jdbc:mysql://localhost:3306/your_database_name?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC" val dbUsername = "your_username" val dbPassword = "your_password" val exportQuery = System.getProperty("dbStatement", "SELECT * FROM your_table limit 1") val targetCsv = new File("data.csv") // 执行数据导出逻辑 Class.forName("com.mysql.cj.jdbc.Driver") val dbConnection = DriverManager.getConnection(jdbcUrl, dbUsername, dbPassword) try { val statement = dbConnection.createStatement() val resultSet = statement.executeQuery(exportQuery) val metaData = resultSet.getMetaData val columnCount = metaData.getColumnCount // 提取表头 val headers = (1 to columnCount).map(metaData.getColumnName).toList // 初始化CSV写入器并写入表头 val csvWriter = CSVWriter.open(targetCsv) csvWriter.writeRow(headers) // 遍历结果集,写入每一行数据 while (resultSet.next()) { val rowData = (1 to columnCount).map(resultSet.getString).toList csvWriter.writeRow(rowData) } csvWriter.close() println(s"✅ 数据导出完成,文件路径:${targetCsv.getAbsolutePath}") } finally { // 确保数据库连接被关闭,避免资源泄漏 dbConnection.close() } // 这里可以保留一个空场景,或者如果不需要运行测试可以删除setUp setUp(scenario("DataExport").exec(_ => session => session).inject(atOnceUsers(1))) }
关键修改说明
- 直接使用JDBC API:绕过Gatling的feeder,直接连接数据库、执行查询、遍历结果集,这样能完全控制数据导出的流程,更适合批量导出需求。
- 正确处理CSV表头与数据:从结果集元数据中提取列名作为表头,然后逐行读取数据写入CSV,确保导出的文件格式正确。
- 资源安全管理:用
try-finally确保数据库连接和CSV写入器被正确关闭,避免资源泄漏。 - 修正JDBC URL:把
&替换为&,保证数据库连接正常。 - 移除无用代码:删掉了原来未初始化的变量、重复的写入器等冗余代码,让逻辑更清晰。
额外提示
如果你之后要把这个CSV作为Gatling feeder使用,只需要用csv("data.csv").circular(或其他feeder策略)加载即可,完全没问题。
内容的提问来源于stack exchange,提问作者Ema
相关产品推荐
相关产品推荐

