更改批量删除的 where 子句

Change where clause for batch delete

我想创建一个批量删除类似这样的东西: 在 t.my_attribute = ?

处删除 t

第一次尝试是:

   private void deleteRecord( ) {
      //loop
      final MyRecord myRecord = new MyRecord();
      myRecord.setMyAttribute(1234);
      getDslContext().batchDelete(myRecord) .execute();
   }

但是这里 SQL 总是包含 pk 而不是我的属性。

第二次尝试是创建一个带有绑定值的 delete 语句,但在这里我没有找到解决方法,如何使用 ?

创建一个 where 子句
  //loop
  getDslContext().delete( MY_RECORD ).where( ???)
        .bind( 12234 );

有人可以进一步帮助我吗?

DELETE 语句本身

只需像 SQL 中那样添加 comparison predicate:

getDslContext()
    .delete(T)
    .where(T.MY_ATTRIBUTE.eq(12234))
    .execute();

这是假设您使用的是 code generator,因此您可以静态导入 com.example.generated.Tables.T table 参考。

批处理那个

在 jOOQ 中,您有两种批处理此类语句的选项:

1.使用显式批处理 API

As explained here,创建一个带有虚拟绑定值的查询,如上所示,但不要直接执行它,而是使用 Batch API:

// Assuming these are your input attributes
List<Integer> attributes = ...

Query query = getDslContext().delete(T).where(T.MY_ATTRIBUTE.eq(0));
getDSLContext()
    .batch(query)
    .bind(attributes
        .stream().map(a -> new Object[] { a }).toArray(Object[][]::new)
    ).execute();

2。在批处理连接中收集单个执行

您始终可以使用 jOOQ 中方便的 batched collection 来透明地收集已执行的 SQL 并将其延迟到一个批处理中:

getDslContext().batched(c -> {
    for (Integer attribute : attributes)
        c.dsl().getDslContext()
               .delete(T)
               .where(T.MY_ATTRIBUTE.eq(attribute)
               .execute(); // Doesn't execute the query yet
}); // Now the entire batch is executed

在后一种情况下,对于每次执行,SQL 字符串可能是 re-generated,因此对于简单的批处理,前者可能更好。

批量执行

但是,当您可以 运行 单个查询时,为什么要进行批处理?也许就这样做吧?

getDslContext()
    .delete(T)
    .where(T.MY_ATTRIBUTE.in(attributes))
    .execute();