如何在jooq中清除批处理?

8iwquhpp  于 2021-07-29  发布在  Java
关注(0)|答案(1)|浏览(360)

我试图在执行多个插入时重用一个准备好的语句。像这样的

InsertValuesStepN<Record> batch = create.insertInto(table, fields);
for(int i=0; i<100000; i++) {
    batch.values();
    if(i % 1000 == 0) {
        batch.execute();
        // need to call clearBatch here so we don't insert records twice
    }
}

但是在调用execute之后,我看不到任何方法可以让insertvaluesstepn清除它的记录。这可能吗?

gwo2fgha

gwo2fgha1#

为每个批创建新语句:

您可以在每个批上创建一个新语句,而不是重用上一个语句。

InsertValuesStepN<Record> batch = null;
for(int i=0; i<100000; i++) {
    if (batch == null)
        batch = create.insertInto(table, fields);

    batch.values();
    if(i % 1000 == 0) {
        batch.execute();
        batch = null;
    }
}

使用bind()api

由于性能问题#6616,通常不建议这样做,但由于瓶颈(根据您的评论)是创建新的准备语句,因此您可以尝试使用 Query.bind() api,您可以在第二批、第三批等批处理中使用它来用现有查询中的新值替换现有绑定值。呼叫 Query.bind() 这样地:

// Create the initial statement with dummy values for your batch
Query batch = create.insertInto(table, fields).values(...).keepStatement(true);
for(int i=0; i<100000; i += 1000) {

    // Call this once for each bind value
    batch.bind(...);
    batch.execute();

    // Handle the last insertions, where you have less than 1000 rows per insert
    // ...
}

代理jdbc

您可以实现一个代理jdbc PreparedStatement 当jooq调用时,这实际上并没有关闭delegate语句 PreparedStatement.close() ,但保持打开状态,并在jooq再次尝试准备时再次向jooq提供相同的语句。
有一个悬而未决的功能请求提供这样一个 PreparedStatement 开箱即用缓存:https://github.com/jooq/jooq/issues/7327,或者,您的jdbc驱动程序已经有了一个(例如oracle)。

使用导入api

但也许,您实际上使用的是for jooq的import api,它允许指定批处理、批量和提交大小,例如。

create
   .loadInto(table)
   .bulkAfter(1000)
   .loadArrays(...) // There are other possible data sources
   .fields(fields)
   .execute();

相关问题