春季启动-部分更新最佳实践



我正在使用带有mongo数据库的Spring引导v2。我想知道对数据模型进行部分更新的最佳方法是什么。假设我有一个具有x个属性的模型,根据请求,我可能只想更新其中的1个、2个或x个属性。我应该为每种类型的更新操作公开一个端点,还是可以公开一个终结点并以通用的方式进行?注意:我需要能够验证请求属性的内容(例如,电话号码必须仅为数字(

谢谢,

HTTP PATCH是通过只指定已更改的属性来更新资源的好方法。下面的博客很好地解释了

您实际上只能公开一个端点。这是我几个月前的情况:

我希望人们修改项目文档的任何(甚至所有(字段(我是谁来强迫用户手动提供所有字段?哈哈(。所以我有了我的模型,Project.java:

package com.foxxmg.jarvisbackend.models;
//imports
@Document(collection = "Projects")
public class Project {
@Id
public String id;
public String projectTitle;
public String projectOverview;
public Date startDate;
public Date endDate;
public List<String> assignedTo;
public String progress;
//constructors
//getters & setters
}

我有我的存储库:

项目存储库.java

package com.foxxmg.jarvisbackend.repositories;
//imports
@Repository
public interface ProjectRepository extends MongoRepository<Project, String>, QuerydslPredicateExecutor<Project> {
//please note, we are going to use findById(string) method for updating
Project findByid(String id);
//other abstract methods 

}

现在转到我的控制器ProjectController.java:

package com.foxxmg.jarvisbackend.controllers;
//import
@RestController
@RequestMapping("/projects")
@CrossOrigin("*")
public class ProjectController {
@Autowired
private ProjectRepository projectRepository;
@PutMapping("update/{id}")
public ResponseEntity<Project> update(@PathVariable("id") String id, @RequestBody Project project) {
Optional<Project> optionalProject = projectRepository.findById(id);
if (optionalProject.isPresent()) {
Project p = optionalProject.get();
if (project.getProjectTitle() != null)
p.setProjectTitle(project.getProjectTitle());
if (project.getProjectOverview() != null)
p.setProjectOverview(project.getProjectOverview());
if (project.getStartDate() != null)
p.setStartDate(project.getStartDate());
if (project.getEndDate() != null)
p.setEndDate(project.getEndDate());
if (project.getAssignedTo() != null)
p.setAssignedTo(project.getAssignedTo());
return new ResponseEntity<>(projectRepository.save(p), HttpStatus.OK);
} else
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}

这将允许使用Spring Boot在MongoDB中进行部分更新。

如果你正在使用Mapstruct,那么这个博客非常有用https://cassiomolin.com/2019/06/10/using-http-patch-in-spring/

这个想法很简单,

  • 从DB加载实体
  • 将该实体转换为与API请求中发送的有效负载相同的数据类型
  • 然后对有效负载应用合并/修补操作&从上一步转换的dto[utlityincluded]
  • 输出被合并为
  • 将合并后的数据转换为实体
  • 保存实体

博客中的示例:

@PatchMapping(path = "/{id}", consumes = "application/json-patch+json")
public ResponseEntity<Void> updateContact(@PathVariable Long id,
@RequestBody JsonPatch patchDocument) {
// Find the domain model that will be patched
Contact contact = contactService.findContact(id).orElseThrow(ResourceNotFoundException::new);

// Map the domain model to an API resource model
ContactResourceInput contactResource = contactMapper.asContactResourceInput(contact);

// Apply the patch to the API resource model
ContactResourceInput contactResourcePatched = patch(patchDocument, contactResource, ContactResourceInput.class);
// Update the domain model with the details from the API resource model
contactMapper.update(contactResourcePatched, contact);

// Persist the changes
contactService.updateContact(contact);
// Return 204 to indicate the request has succeeded
return ResponseEntity.noContent().build();
}

p.S使用mapstruct,您可以轻松控制属性映射,将某些内容映射到其他内容,甚至忽略,如果您有customerId长类型,并且希望将其映射到customer,这是有益的

如果您使用的是Spring Data MongoDB,您有两个选项,要么使用MongoDB Repository,要么使用MongoTemplate。

最新更新