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

如何基于CSV创建JOOQ模拟数据库及绑定值异常排查

JOOQ Mock数据库CSV加载与INSERT异常解决

关于SQL绑定值的疑问

先明确一点:你看到的带?的SQL是预编译SQL语句,绑定值其实已经正确处理了——从你打印的getBindValues()和getParams()就能看出来,50331和1556686800已经和占位符关联上了。

你遇到的异常问题,核心不在绑定值,而是Mock环境的执行逻辑:JOOQ的MockConnection不会真的执行INSERT语句,而是完全依赖你在execute()方法里模拟的返回结果。你原来的代码返回了一个空的Result,JOOQ就会认为这次INSERT没有成功插入任何行,所以抛出了DataAccessException。

在Mock中添加CSV文件加载功能

你提到的CsvLoader返回Loader<Record>,其实只需要调用它的execute().result()就能拿到Result<Record>,刚好符合MockResult的需求。下面是调整后的完整代码,分场景处理不同SQL操作:

步骤1:提前加载CSV数据(避免重复IO)

可以在Mock类的初始化阶段加载CSV数据,这样每次执行查询时不用重复读取文件:

private final Result<MyTableRecord> csvData;

public YourMockDataProvider(Configuration configuration) {
    DSLContext create = DSL.using(configuration);
    // 加载CSV文件到Result中
    this.csvData = create.loadInto(MY_TABLE)
        .loadCSV(new File("your/csv/file/path.csv"))
        .fields(MY_TABLE.ID, MY_TABLE.EPOCH_TIME) // 指定CSV对应的表字段
        .execute()
        .result();
}

步骤2:修改execute()方法,分SQL类型处理

@Override
public MockResult[] execute(MockExecuteContext context) throws SQLException {
    String sql = context.sql().toLowerCase();

    // 处理INSERT语句:模拟插入成功,返回受影响行数
    if (sql.startsWith("insert into")) {
        // 这里的数字代表受影响行数,和你实际要插入的行数一致即可
        return new MockResult[] { new MockResult(1, null) };
    }

    // 处理SELECT语句:返回CSV加载的数据作为查询结果
    if (sql.startsWith("select")) {
        return new MockResult[] { new MockResult(csvData.size(), csvData) };
    }

    // 其他类型SQL(比如UPDATE/DELETE)可以按需添加模拟逻辑
    return new MockResult[0];
}

关键说明

  • INSERT操作:Mock不需要实际写入数据,只需要告诉JOOQ“这次插入影响了N行”即可,所以MockResult的第二个参数传null(因为INSERT没有结果集)。
  • SELECT操作:直接把提前加载好的CSV数据作为结果集返回,MockResult的第一个参数是结果集的行数,第二个是结果集对象。
  • CSV字段映射:确保fields()方法指定的字段顺序和CSV文件的列顺序一致,避免数据错位。

这样修改后,你的INSERT操作会被Mock成成功执行,SELECT操作则会返回CSV里的模拟数据,解决之前的异常问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:09:07