跳到主要内容

Upsert Mask

被保存对象的已加载形状决定哪些值可用。UpsertMask进一步限制upsert时哪些属性允许插入、 哪些属性允许更新。例如,完整的输入书籍可以提供所有插入值,但冲突时只允许更新价格。

选择可更新属性

sqlClient
.saveCommand(book)
.setUpsertMask(BookProps.PRICE)
.execute();

插入时仍然使用正常的已加载值。冲突时,普通更新属性集合是已加载形状与mask的交集,并排除 冲突id或key。Mask不会加载缺失的值。

Mask同样约束公开的保存赋值表达式的目标。为对象形状或mask没有选中的目标 配置自定义表达式会报错。

不更新对象属性

sqlClient
.saveCommand(book)
.forbidUpdate()
.execute();

forbidUpdate()让upsert更新分支不选择任何实体属性赋值。向便捷形式的setUpsertMask(...) 重载显式传入空数组,含义相同。

这不会把操作改成INSERT_IF_ABSENT。方言仍可能为了获取id、返回数据行或保持其他保存语义而 执行自赋值SQL,这样的SQL可能触发数据库触发器。有效的setUpdateWhere仍然决定是否接受匹配 分支。如果业务意图是跳过已有行,请使用保存模式INSERT_IF_ABSENT

配置两个分支

插入和更新需要不同的属性集合时,使用UpsertMask对象:

UpsertMask<Book> mask = UpsertMask.of(Book.class)
.addInsertableProp(BookProps.NAME)
.addInsertableProp(BookProps.EDITION)
.addInsertableProp(BookProps.PRICE)
.addUpdatableProp(BookProps.PRICE);

sqlClient.saveCommand(book).setUpsertMask(mask).execute();

每个分支在未配置属性列表前都不受限制。addInsertablePathaddUpdatablePath可以选择嵌入 对象的单个成员。Mask构建方法返回新的mask,应保留返回值或链式调用。

forbidInsert()从空的插入属性列表开始,并不是禁用插入分支。可以在之后添加需要插入的属性。 冲突列以及框架必需的列仍然会提供,省略的列在可用时使用数据库默认值。缺少没有默认值的必填值 仍然会导致正常的数据库错误。

Mask选择的是赋值,它不能替代保存模式更新条件版本模式