当前位置: 首页 > 知识库问答 >
问题:

使用Spring Data Rest和MongoDB更新特定字段

陶飞英
2023-03-14

我正在使用Spring Data MongoDB和Spring Data Rest创建一个Rest API,它允许对我的MongoDB数据库进行GET、POST、PUT和DELETE操作,除了更新操作(PUT)之外,其他操作都很好。只有当我在请求体中发送完整对象时,它才起作用。

@Document
public class User {
    @Id
    private String id;
    private String email;
    private String lastName;
    private String firstName;
    private String password;

    ...
}

我试着在这里搜索一个解决方案,但我只找到了以下帖子,但没有解决方案:如何使用MongoRepository接口更新mongo db中的特定字段?

这有没有办法实施?

共有1个答案

姚俊材
2023-03-14

Spring Data Rest使用Spring数据存储库使用Rest调用(查看https://docs.Spring.io/spring-data/Rest/docs/current/reference/html/#reference)自动检索和操作持久数据。

使用Spring Data MongoDB时,您有MongoOperations接口,该接口用作Restendpoint的存储库。然而,MongoOperations目前不支持特定字段更新!

PS:如果他们在Spring Data JPA中添加@DynamicUpdate这样的特性,那就太棒了

但这并不意味着它可以做,这里是我做的变通当我有这个问题。

首先让我解释一下我们要做什么:

  1. 我们将创建一个控制器,该控制器将覆盖所有PUT操作,以便实现自己的更新方法。
  2. 在update方法中,我们将使用MongoTemplate,它确实具有更新特定字段能力。
<dependency>
    <groupId>org.reflections</groupId>
    <artifactId>reflections</artifactId>
    <version>0.9.12</version>
</dependency>
public class UpdateUtility {

    private static final String MODEL_PACKAGE = "com.mycompany.myproject.models";
    private static boolean initialized =  false;
    private static HashMap<String, Class> classContext = new HashMap<>();

    private static void init() {
        if(!initialized) {
            Reflections reflections = new Reflections(MODEL_PACKAGE);
            Set<Class<?>> classes = reflections.getTypesAnnotatedWith(Document.class); // Get all the classes annotated with @Document in the specified package

            for(Class<?> model : classes) {
                classContext.put(model.getSimpleName().toLowerCase(), model);
            }

            initialized = true;
        }
    }

    public static Class getClassFromType(String type) throws Exception{
        init();
        if(classContext.containsKey(type)) {
            return classContext.get(type);
        }
        else {
            throw new Exception("Type " + type + " does not exists !");
        }
    }
}
public class UpdateController {

    @Autowired
    private MongoTemplate mongoTemplate;

    @PutMapping("/{type}/{id}")
    public Object update(@RequestBody HashMap<String, Object> fields,
                                  @PathVariable(name = "type") String type,
                                  @PathVariable(name = "id") String id) {
        try {
            Class classType = UpdatorUtility.getClassFromType(type); // Get the domain class from the type in the request
            Query query = new Query(Criteria.where("id").is(id)); // Update the document with the given ID
            Update update = new Update();

            // Iterate over the send fields and add them to the update object
            Iterator iterator = fields.entrySet().iterator();
            while(iterator.hasNext()) {
                HashMap.Entry entry = (HashMap.Entry) iterator.next();
                String key = (String) entry.getKey();
                Object value = entry.getValue();
                update.set(key, value);
            }

            mongoTemplate.updateFirst(query, update, classType); // Do the update
            return mongoTemplate.findById(id, classType); // Return the updated document
        } catch (Exception e) {
            // Handle your exception
        }
    }
}

现在,我们可以更新指定的字段,而不需要更改调用。因此在您的情况下,呼叫将是:

PUT http://MY-DOMAIN/user/MY-USER-ID { lastName: "My new last name" }

PS:你可以通过增加在嵌套对象中更新特定字段的可能性来改进它...

 类似资料:
  • 本文向大家介绍MongoDB中如何使用特定字符串更新字段的所有值,包括了MongoDB中如何使用特定字符串更新字段的所有值的使用技巧和注意事项,需要的朋友参考一下 要更新所有值,请将update()与multi:true一起使用。  让我们创建一个包含文档的集合- 在find()方法的帮助下显示集合中的所有文档- 这将产生以下输出- 以下是更新字段“ SubjectName”的所有值的查询- 在f

  • 问题内容: 是否有更新的方式只有一些领域使用该方法的实体对象从春数据JPA? 例如,我有一个这样的JPA实体: 通过其CRUD存储库: 在Spring MVC中,我有一个控制器,该控制器获取用于更新它的对象: 我知道我可以使用来加载用户findOne,然后更改其名称并使用save…来更新它。但是,如果我有100个字段,而我想更新其中的50个字段,则更改每个值可能会很烦人。 有没有办法告诉类似“ 保

  • 有没有办法使用Spring Data JPA中的方法只更新实体对象的某些字段? 我知道我可以使用加载用户,然后更改其名称并使用更新它...但是,如果我有100个字段,我想更新其中的50个,这可能是非常恼人的更改每个值… 难道没有办法告诉像“保存对象时跳过所有空值”这样的事情吗?

  • 在我的MongoDB中,我有文档,如下所示。如何更新内部文档结构中的文档:<code>〔{1},〔{2}〕,〔{3}〕、〔{4}〕</code>。 例如:子子文档中的子文档具有和以及 和

  • 本文向大家介绍使用$ set和location $运算符更新数组中的特定MongoDB文档?,包括了使用$ set和location $运算符更新数组中的特定MongoDB文档?的使用技巧和注意事项,需要的朋友参考一下 要使用$set和positional运算符更新数组中的特定文档,请使用MongoDB 。该基于查询过滤器集合中更新单个文件。 让我们创建一个包含文档的集合- 在方法的帮助下显示集合

  • 以下是我要保存(创建/更新)的实体模型: 有两种方法可以更新此实体: < li >第一个更新除< code>notified属性以外的所有属性的人 < li >第二个更新< code>notified属性的仅 有没有办法告诉Hibernate忽略某个特定方法的某些字段?我需要创建两个不同的特定dao方法吗?我是否需要为经典的< code>save方法保留< code>updatable=false