MongoTemplate中setOnInsert与set方法的深度解析

MongoTemplate中setOnInsert与set方法的深度解析

在Spring Data MongoDB的MongoTemplate中,setOnInsertset方法都是在更新文档时使用的,但它们在处理upsert操作(即,如果文档不存在则插入,存在则更新)时扮演着截然不同的角色。

核心区别:操作的触发时机

setOnInsertset最核心的区别在于它们执行的条件:

  • set(): 无论操作是更新现有文档还是插入新文档,set()方法指定的字段都会被设置或更新。
  • setOnInsert(): setOnInsert()方法指定的字段仅在upsert操作导致新文档被插入时才会被设置。如果upsert操作匹配到了现有文档并进行更新,那么setOnInsert()中的设置将被忽略。

可以简单地理解为,setOnInsert是为新插入的文档设置一个初始值或默认值,而set则是对文档进行常规的更新。

使用场景与代码示例

setOnInsertset通常与upsert: true选项结合使用。 upserttrue意味着,如果查询条件没有找到匹配的文档,MongoDB将会创建一个新的文档。

场景示例: 假设我们有一个products集合,我们希望在产品首次被添加到数据库时设置一个默认的库存数量(defaultQty),同时在每次更新时都更新产品的名称(item)。

使用MongoTemplate实现:

import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

// ...

public void upsertProduct(MongoTemplate mongoTemplate, String productId, String itemName) {
    Query query = new Query(Criteria.where("_id").is(productId));

    Update update = new Update()
            .set("item", itemName)
            .setOnInsert("defaultQty", 100);

    mongoTemplate.upsert(query, update, "products");
}

操作结果分析:

  • productId对应的文档不存在时:

    • upsert操作会创建一个新的文档。
    • set("item", itemName)会被执行,新文档的item字段被设置为itemName
    • setOnInsert("defaultQty", 100)也会被执行,新文档的defaultQty字段被设置为100
    • 最终插入的文档为:{ "_id": productId, "item": "newItemName", "defaultQty": 100 }
  • productId对应的文档已存在时:

    • upsert操作会匹配到现有的文档。
    • set("item", itemName)会被执行,现有文档的item字段被更新为新的itemName
    • setOnInsert("defaultQty", 100)将被忽略,因为没有发生插入操作。
    • 如果原文档是{ "_id": productId, "item": "oldItemName", "defaultQty": 50 },更新后的文档将是{ "_id": productId, "item": "newItemName", "defaultQty": 50 }

注意事项

  • 字段不能重复: 在同一个Update对象中,同一个字段不能同时出现在set()setOnInsert()中,否则会引发错误。
  • upsert是关键: setOnInsert的效果完全依赖于upsert操作。如果upsertfalse(默认情况),setOnInsert将永远不会生效。

总结

总的来说,setsetOnInsert为在MongoTemplate中执行upsert操作提供了强大的灵活性:

方法描述使用场景
set()无论文档是插入还是更新,都设置或更新指定的字段。需要对字段进行常规更新,不论其是否存在。
setOnInsert()仅在upsert操作插入新文档时设置指定的字段。为新创建的文档设置创建时间、初始状态、默认值等一次性属性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰糖心书房

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值