Spring mvc 使用Spring数据MongoDB和Spring MVC更新对象/文档的模式

Spring mvc 使用Spring数据MongoDB和Spring MVC更新对象/文档的模式,spring-mvc,spring-data,spring-boot,spring-data-mongodb,Spring Mvc,Spring Data,Spring Boot,Spring Data Mongodb,我试图提出一种可重用的模式,用于在结合使用Spring数据和Spring MVC时更新MongoDB文档 用例通常可以总结为: 使用repository.save()在Mongo中创建文档 然后,该文档的部分内容以SpringMVC可编辑的形式呈现 用户提交该文档的更新部分,然后保存 如果在步骤3中使用repository.save()方法,我将丢失文档中未绑定到表单的所有数据。让表单负责整个文档是脆弱的,因此MongoTemplate的findAndModify()方法似乎就在这里派上了用场

我试图提出一种可重用的模式,用于在结合使用Spring数据和Spring MVC时更新MongoDB文档

用例通常可以总结为:

  • 使用repository.save()在Mongo中创建文档
  • 然后,该文档的部分内容以SpringMVC可编辑的形式呈现
  • 用户提交该文档的更新部分,然后保存
  • 如果在步骤3中使用repository.save()方法,我将丢失文档中未绑定到表单的所有数据。让表单负责整个文档是脆弱的,因此MongoTemplate的findAndModify()方法似乎就在这里派上了用场

    为了使用findAndModify()方法,我创建了支持toMap()方法的表单对象,该方法将表单对象的属性作为映射,并删除一些字段(例如class和id)。这会得到一个映射,其中只包含表单对象中我关心的字段。将对象ID和该映射传递给自定义存储库上的update()方法,我构建了可以传递给findAndModify()方法的查询和更新对象

    使用这种方法,我可以很容易地将字段添加到对象中,并且只需要担心在表单发布中存在我不想更新的字段时的实例。应保留表单未处理的文档字段。同时使用Repository和MongoTemplate似乎有点复杂,所以我想知道是否有更好的例子来处理这个问题。在使用Mongo和SpringMVC时,这似乎应该是一种一致的模式(至少)

    我创建了一个示例项目,展示了如何在GitHub上实现此模型。Spock测试显示了使用save()来“更新”文档将如何像预期的那样清除字段以及我的update()方法


    当使用Spring MVC和Spring数据处理文档的部分更新时,其他人在做什么?

    如果你拿走了用户提供的任何东西,只是把它们放在数据库中,你就有可能做一些危险的事情,比如更新或创建他们不应该做的数据。相反,您应该首先查询Mongo以获取文档的最新版本,更改任何字段(看起来您使用的是Groovy,这样您就可以遍历所有属性并在新文档上设置它们),然后保存新的完整文档


    如果要进行小规模、一致的更新(如增加投票数等),可以使用
    MongoTemplate
    创建一个自定义MongoDB查询,对几个字段进行更新。查看
    spring数据mongodb
    了解更多信息。您还可以向使用
    MongoTemplate的
    MongoRepository
    中添加自定义方法。其目的是不要将用户提供的所有内容都放入数据库中。用户只能提供表单中的数据字段。对于我的简单示例,我让表单扩展模型对象,但这不是必需的。我还可以在toMap()方法中排除“用户提供的”字段。更新()我在自定义存储库中创建的方法确实使用MongoTemplate进行查询和更新,但来自JPA/Hibernate,这似乎比我预期的代码多了一点,我想知道是否有更好的方法,或者这只是Mongo具有更大灵活性的副作用。@watchwithmike您是否能够通过任何方式解决此问题chance?@VishwasShashidhar我最终使用了您可以在应用程序中找到的模式,您可以将这些模式配置为使用MongoDB。[创建实体页面](Creating a entity page)[提供了项目在实体方面所做工作的概述,您只需要确保将其配置为使用MongoDB而不是JPA。我只是使用JHipster作为参考,而不是从它开始整个项目。希望对您有所帮助。