spring 自带的mongoRepository ,只能replace更新,即全量更新,我们可以自定义一个repository 方法。来做部分更新
1.解决思路就是生成一个map,对map中不为空的key生成update查询
Map<String, Object> objectMap = user.toMap();
objectMap.values().removeIf(Objects::isNull);
Update update = new Update();
objectMap.forEach(update::set);
return mongoOperations.findAndModify(
Query.query(Criteria.where("_id").is(user.getId())), update, User.class);
2.而转换成map,可以用spring自带的jackson
ObjectMapper m = new ObjectMapper();
Map<String,Object> props = m.convertValue(myBean, Map.class);
3.需要注意的,对于基本类型的字段,有默认值的,所以推荐使用Object类型,如别用int 用Integer。null不占用mongodb的空间,即不会存储。所以从这方面也是好的。全部代码如下,注意笔者用的Reative版:
public Mono<UpdateResult> updatePartial(MySeries mySeries) {
if (null == mySeries || null == mySeries.getSrcId()) {
return null;
}
ObjectMapper m = new ObjectMapper();
Map<String, Object> objectMap = m.convertValue(mySeries, Map.class);
objectMap.values().removeIf(o -> {
if (null == o) {
return true;
}
var cls = o.getClass();
if (cls == ArrayList.class && ((ArrayList) o).size() <= 0) {
return true;
}
if (cls == String.class && StringUtils.isEmpty(o)) {
return true;
}
return false;
});
Update update = new Update();
objectMap.forEach(update::set);
Query q = new Query();
q.addCriteria(Criteria.where("srcId").is(mySeries.getSrcId()));
return template.updateFirst(q, update, MySeries.class);
}
、