如何使用csv文件为JOOQ创建模拟数据库?

时间:2019-06-09 04:41:51

标签: java csv mocking jooq

我已阅读以下文章,并尝试从csv加载数据以创建模拟数据库。

https://blog.jooq.org/tag/mock-data/

https://www.jooq.org/doc/3.11/manual/sql-execution/importing/importing-csv/

但是最终出现以下例外情况。

错误详细信息:

org.jooq.exception.DataAccessException: SQL [insert into `database_name`.`table_name` (`id`, `epoch_time`) values (?, ?)]; Invalid SQL: insert into `database_name`.`table_name` (`id`, `epoch_time`) values (?, ?)

已处理的行数:1

存储的行数(INSERT或UPDATE):0

被忽略的行数(由于错误或重复的规则):1

查询查询= error.query();

System.out.println(query.getSQL());

insert into `database_name`.`table_name` (`id`, `epoch_time`) values (?, ?)

System.out.println(query.getBindValues());

[50331, 1556686800]

System.out.println(query.getParams());

{1=50331, 2=1556686800}

问题

我对Jooq的理解不是很好。

  1. 上面的SQL中的值是否未绑定?

  2. 我不确定如何在下面的代码中添加加载CSV文件的功能。 Csv Loader会发回Loader<Record>,其中MockResult需要Result<Record>

    @Override
    public MockResult[] execute(MockExecuteContext context) 
    throws SQLException {
    
    // Use ordinary jOOQ API to create an org.jooq.Result object.
    // You can also use ordinary jOOQ API to load CSV files or
    // other formats, here!
    DSLContext create = DSL.using(configuration);
    Result<MyTableRecord> result = create.newResult(MY_TABLE);
    result.add(create.newRecord(MY_TABLE));
    
    // Now, return 1-many results, depending on whether this is
    // a batch/multi-result context
    return new MockResult[] {
        new MockResult(1, result)
        };
    }
    

1 个答案:

答案 0 :(得分:0)

好的,我完全错了。

我的印象很深刻,您可以使用以下API将数据加载到内存表中,并创建一个由一些必需表组成的模拟数据库,并对它运行一些查询。

// Load data into the BOOK table from an input stream
// holding the CSV data.
create.loadInto(BOOK)
      .loadCSV(inputstream, encoding)
      .fields(BOOK.ID, BOOK.AUTHOR_ID, BOOK.TITLE)
      .execute();

花了几个小时弄清楚如何从csv加载数据(如下所述)后才意识到, jooq (一种写查询的很棒的api)不是数据库引擎,实际上并不能对内存中的数据执行查询。

从csv加载模拟数据:

@Override
public MockResult[] execute(MockExecuteContext ctx) throws SQLException {


    List<String> strings = Files.readAllLines(Paths.get("table_data.csv"));
    String csvString = strings.stream()
            .reduce(new StringJoiner("\n"), StringJoiner::add, StringJoiner::merge)
            .toString();

    DSLContext create = DSL.using(SQLDialect.MYSQL);

    Result<Record> records = create.fetchFromCSV(csvString);
    List<YourTableDataRecord> tableDataList = records.into(YourTableDataRecord.class);

    Result<YourTableDataRecord> result = create.newResult(POJO_RERESENTING_THE_DATA);

    result.addAll(tableDataList);

    return new MockResult[]{
            new MockResult(result.size(), result)
    };
}

请注意,上述解决方案可以更高效地完成,可以逐行读取并缓存结果。

此外,应针对每个查询创建模拟结果。在https://blog.jooq.org/tag/unit-testing/部分为此使用jOOQ的MockDataProvider

中了解更多信息