首页 » 文章 » spring data mongodb 部分更新文档

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);

    }

添加新评论