如何使用动态查询参数通过 jOOQ 创建批量更新

How to create a batch update with jOOQ using dynamic query parameters

提问人:randy 提问时间:11/16/2023 最后编辑:randy 更新时间:11/16/2023 访问量:24

问:

我在 Spring Boot 中使用 Groovy,我的实例与文档中的实例基本相同。假设所有未定义的事物都是它们应该有的样子......jooqcreate

我们过去做过这样的事情:

int bulkUpdate(List<Thing> things) {
    UpdateSetMoreStep update = jooq.update(TABLE)

    things.each { Thing thing ->
        update.set(getField(thing.prop1), thing.value)
    }

    return update.where(CONDITION).execute()
}

这工作正常。

我正在寻找的是如何批量执行此操作。这意味着,我可能有一个有 100 个项目,我需要动态定义 100 个实例,并且我想一次执行它们(一个数据库事务,全有或全无)。List<Thing>update

做这样的事情是唯一的选择吗?

int bulkUpdate(List<Thing> things) {
    UpdateSetMoreStep update = jooq.update(TABLE)

    def updates = things.collect { Thing thing ->
        return update.set(getField(thing.prop1), thing.value)
    }

    return jooq.batch(updates).execute().sum()
}

我在这里的实际用例要复杂得多,每次迭代都需要子选择和(我认为)多次更新。所以我只是想了解我是否在文档/API 中遗漏了某些内容,或者这是否是完成此任务的最佳/唯一方法。

为了澄清一下我在寻找什么,我们经常做这样的事情,这是在循环中完成很多事情的好方法:

int bulkInsert(List<Thing> things) {
    InsertValuesStep<N> insertStep = jooq.insertInto(TABLE).columns(col1, col2)

    things.each {
        insertStep = insertStep.values(it.prop1, it.prop2)
    }

    return insertStep.execute()
}

有没有办法对批处理做类似的事情?喜欢这个:

int bulkUpdate(List<Thing> things) {
    def batch = jooq.batch()
    UpdateSetMoreStep update = jooq.update(TABLE)

    things.each { Thing thing ->
        batch += update.set(getField(thing.prop1), thing.value)
    }

    batch.execute().sum()
}

同样,没有错,但我想知道这是否是唯一的方法,或者 API 中是否有更方便的东西,就像我的上一个例子一样。jooq.batch(updates).execute()

最后,我被困在 推出的任何版本的 jOOQ 上,我认为是 3.12。我当然愿意听到新版本中可用的选项,但理想情况下,我们专注于我可以“今天”实施的解决方案。spring-boot-starter-jooq:2.6.9

谢谢!

Jooq的

评论


答:

0赞 Lukas Eder 11/16/2023 #1

一个可能更方便的方法是使用 jOOQ 的批处理连接,它在后台透明地批处理内容,延迟语句直到触发任何批处理刷新条件,包括:

  • 语句的 SQL 更改
  • 达到批量大小
  • 交易提交
  • 批处理连接已关闭

最后,我被困在使用 spring-boot-starter-jooq:2.6.9 推出的任何版本的 jOOQ 上,我认为是 3.12

这是相当武断的限制。您可以独立于 Spring Boot 升级 jOOQ。但是,如果这是不可能的,您也可以从最新的jOOQ版本中复制并仅使用它。BatchedConnection

评论

0赞 randy 11/17/2023
我很欣赏你的回应,卢卡斯。但是,这是在一组相当复杂的操作中发生的,我需要直接控制批处理的执行时间。是的,这是一个任意的限制;我们“非常小心”地保持同步,因此不会出现意外中断。我梦想着“有一天”。
0赞 Lukas Eder 11/17/2023
@randy:我的意思是,我只是想给你一个选择,因为这是你要求的,但我真的不明白你的问题。您的方法奏效了,它为您提供了所需的细粒度控制。那么,你到底在期待什么? 并且是完全不同的陈述,因此自然而然地,它们的工作方式并不完全相同。我真的不明白为什么这个案子会困扰你,但不是这个案子......INSERTUPDATEUPDATEINSERT
0赞 randy 11/17/2023
我认为这只是因为我可以直接与实例交互以实现“批量插入”。而实例不是那样工作的;它需要一个完全独立的操作。在某种程度上,感觉 API 缺少一些东西,或者在这方面不一致。不要误会我的意思,我喜欢jOOQ,并感谢你所做的一切。从根本上说,我理解这一点,并且在 SQL 中是不同的。收集到批处理方法当然没有错,我只是认为可能有更类似于插入方法的东西。insertupdateINSERTUPDATE
0赞 Lukas Eder 11/17/2023
@randy:嗯,有 ,如果你只使用子句,你可以将其用作更复杂的 ,或者如果你的 RDBMS 支持它(和/或 jOOQ 可以模拟它)MERGEUPDATEWHEN MATCHED THEN UPDATEUPDATE .. FROM