Spring Data Mongo如何从@Document对象通用生成Update对象或实现upsert
对应实现方案说明
现成API存在,无需自行实现转换逻辑
Spring Data MongoDB 官方已提供对应工具方法,可直接实现你的需求:
核心依赖API
MongoConverter:负责将@Document注解的Java对象转换为Mongo可识别的Bson Document,自动处理字段名映射、类型转换等逻辑Update.fromDocument(Document):静态方法,传入转换后的Bson Document即可自动生成UpdateDefinition实例,自动过滤null值字段,完全符合你要求的「已赋值字段覆盖、null字段不更新」规则
通用实现代码示例
import org.bson.Document; 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; import org.springframework.data.mongodb.core.FindAndModifyOptions; import org.springframework.data.mongodb.core.convert.MongoConverter; import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; public <T> T upsert(T doc, MongoTemplate mongoTemplate) { // 1. 提取文档id构造查询条件 MongoConverter converter = mongoTemplate.getConverter(); MongoPersistentEntity<?> entity = converter.getMappingContext().getRequiredPersistentEntity(doc.getClass()); Object id = entity.getIdentifierAccessor(doc).getIdentifier(); Query query = Query.query(Criteria.where("_id").is(id)); // 2. Java对象转Bson Document Document bson = new Document(); converter.write(doc, bson); // 移除_id避免更新时修改主键 bson.remove("_id"); // 3. 生成Update对象,自动过滤null字段 Update update = Update.fromDocument(bson); // 4. 执行upsert,返回最新文档 return mongoTemplate.findAndModify( query, update, FindAndModifyOptions.options().upsert(true).returnNew(true), (Class<T>) doc.getClass() ); }
注意事项
- 上述API要求Spring Data MongoDB版本不低于2.2,低于该版本的场景才需要自行遍历对象字段构造Update
- 该实现无需先查询数据库,所有逻辑在Mongo服务端执行,完全符合你提出的两条要求
- 原生
MongoRepository的save方法不满足需求是因为其逻辑为:传入对象id非空时默认执行更新,若库中无对应文档会直接抛主键冲突异常,不会自动执行插入
内容的提问来源于stack exchange,提问作者dermoritz
相关产品推荐
相关产品推荐

