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

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)))
}

关键修改说明

  1. 直接使用JDBC API:绕过Gatling的feeder,直接连接数据库、执行查询、遍历结果集,这样能完全控制数据导出的流程,更适合批量导出需求。
  2. 正确处理CSV表头与数据:从结果集元数据中提取列名作为表头,然后逐行读取数据写入CSV,确保导出的文件格式正确。
  3. 资源安全管理:用try-finally确保数据库连接和CSV写入器被正确关闭,避免资源泄漏。
  4. 修正JDBC URL:把&替换为&,保证数据库连接正常。
  5. 移除无用代码:删掉了原来未初始化的变量、重复的写入器等冗余代码,让逻辑更清晰。

额外提示

如果你之后要把这个CSV作为Gatling feeder使用,只需要用csv("data.csv").circular(或其他feeder策略)加载即可,完全没问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:14:13