如何使用 JOOQ 批量执行

Posted

技术标签:

【中文标题】如何使用 JOOQ 批量执行【英文标题】:How to batch execute with JOOQ 【发布时间】:2018-04-21 10:55:32 【问题描述】:

我正在使用 JOOQ 调用现有的 mysql 存储过程。我的代码是用 Java 编写的。一切都很好,但是在批量插入时我有点困惑。例如,我有这样的简单:

private void executeBatch(DSLContext context, LinkedList<AbstractRoutine<Void>> procedures) 
        BatchBindStep step = null;
        for (AbstractRoutine<Void> procedure : procedures) 
            step = context.batch (context.select(procedure.asField()));
        

        step.execute();
    

所提供的 LinkedList 中的每个过程都是一个更新或插入过程,具有自己的参数集,并且实际上已准备好执行。我只是想将它们绑定在一起进行批处理。

当我尝试执行上面的代码时,我得到了错误:

Caused by: java.sql.BatchUpdateException: Can not issue SELECT via executeUpdate().

我做错了什么?我应该解决什么问题?我试图在线搜索答案,但似乎使用 JOOQ 两个批处理存储过程调用并不那么受欢迎。我必须这样做以保持与我的 pre-JOOQ 应用程序的其余部分的兼容性....

【问题讨论】:

记录在案,这也是在用户群上问的:groups.google.com/forum/#!topic/jooq-user/o0Zd9rKoxlg 【参考方案1】:

您的存储过程不得执行任何可以作为 Java 输出的结果,因为每个过程都是使用 executeUpdate 函数调用的。

来自 Java 文档

int executeUpdate(String sql) 抛出 SQLException

执行给定的 SQL 语句,可能是 INSERT, UPDATE,或 DELETE 语句或不返回任何内容的 SQL 语句, 例如 SQL DDL 语句。

【讨论】:

【参考方案2】:

As discussed on the user group,目前(从 jOOQ 3.10 开始)jOOQ 中没有对批处理存储过程的开箱即用支持。待处理的功能请求在这里: https://github.com/jOOQ/jOOQ/issues/6813

解决方法

针对您的特定用例有多种解决方法,包括:

使用临时表并在其中加载数据/参数集。 使用 jOOQ 的 batching API 或 data loading API 将数据直接加载到目标表中 如果您的数据库支持,则使用表值参数 绕过 jOOQ 并诉诸普通 JDBC

【讨论】:

【参考方案3】:

正如在上述 Google 小组中与 Lukas Eder 讨论的那样,此功能(批量调用存储过程)将添加到 JOOQ 3.11。

【讨论】:

以上是关于如何使用 JOOQ 批量执行的主要内容,如果未能解决你的问题,请参考以下文章

如何查看 jOOQ 执行的 SQL 语句?

如何查看 jOOQ 在编译时执行的 SQL 语句?

Jooq 使用 MySql 中的记录批量更新

使用 JooQ 从 CSV 中“批量插入”并同时跟踪插入的记录?

带有自定义绑定的 JOOQ 批量插入

jOOQ:如何在选择查询中调用 Sql 用户定义函数