在更新语句中排除空列 - JOOQ

Exclude null columns in an update statement - JOOQ

我有一个 POJO,其中包含可以更新的字段。但有时只需要更新几个字段,其余的都是空的。如何编写忽略空字段的更新语句?遍历非丢失的并动态添加到 set 语句或使用 coalesce 会更好吗?

我有以下查询:

jooqService.using(txn)
        .update(USER_DETAILS)
        .set(USER_DETAILS.NAME, input.name)
        .set(USER_DETAILS.LAST_NAME, input.lastName)
        .set(USER_DETAILS.COURSES, input.courses)
        .set(USER_DETAILS.SCHOOL, input.school)
        .where(USER_DETAILS.ID.eq(input.id))
        .execute()

有没有更好的做法?

我不知道 Jooq,但看起来你可以简单地这样做:

val jooq = jooqService.using(txn).update(USER_DETAILS)
input.name.let {jooq.set(USER_DETAILS.NAME, it)}
input.lastName.let {jooq.set(USER_DETAILS.LAST_NAME, it)}

等...

编辑:在我看来,如上所述明确映射这些字段是最清楚的,但您可以这样做:

val fields = new Object[] {USER_DETAILS.NAME, USER_DETAILS.LAST_NAME}
val values = new Object[] {input.name, input.lastName}
val jooq = jooqService.using(txn).update(USER_DETAILS)
values.forEachIndexed { i, value ->
    value.let {jooq.set(fields[i], value)}
}

您仍然需要在数组中明确且一致地枚举所有字段和值才能使其正常工作。它似乎不太可读,而且更容易出错。

在Java中会是这样的

var jooqQuery = jooqService.using(txn)
        .update(USER_DETAILS);

if (input.name != null) {
    jooqQuery.set(USER_DETAILS.NAME, input.name);
}
if (input.lastName != null) {
    jooqQuery.set(USER_DETAILS.LAST_NAME, input.lastName);
}

// ...

jooqQuery.where(USER_DETAILS.ID.eq(input.id))
        .execute();

除了编写此 UPDATE 语句之外的另一种选择是使用 UpdatableRecord:

// Load a POJO into a record using a RecordUnmapper
UserDetailsRecord r =
jooqService.using(txn)
    .newRecord(USER_DETAILS, input)
    
(0 .. r.size() - 1).forEach { if (r[it] == null) r.changed(it, false) }
r.update();

您或许可以编写一个扩展函数,使其可用于全局的所有 jOOQ 记录,例如作为 r.updateNonNulls().