【问题标题】:How to update a single field using jpa repository using @patch如何使用 @patch 使用 jpa 存储库更新单个字段
【发布时间】:2020-07-19 23:40:14
【问题描述】:

我正在通过 spring boot 开发一个简单的应用程序。我需要限制用户只能更新名称,而不是所有与用户数据相关的文件,但不幸的是,我的代码有一个问题,如果有人以 Json 格式发送数据并更改年龄或任何其他字段将被更新,但正如我所说,我需要用户能够更改唯一的名称,而不是任何其他字段。我不得不提到我正在使用 JPA 存储库和 spring 数据

我的控制器

@RestController
@RequestMapping("/student")
public class StudentController {
    @Autowired
    StudentRepository repository;
    // method i user to only update the name field
    @PatchMapping("/pattt/{id}")

    public ResponseEntity partialUpdateName(
        @RequestBody Student partialUpdate, 
        @PathVariable("id") String id 
    ){
        Student.save(partialUpdate, id);
        return ResponseEntity.ok(repository.save(partialUpdate));
    };
}

JPA 存储库

@Repository
public interface StudentRepository extends JpaRepository<Student, Integer> {}

学生班

@Entity
@Table(name = "student")
public class Student {

    @Id
    @GeneratedValue
    private int id;
    private String name;
    private int age;
    private String emailAddress;

    public Student() {  }
    public Student(int id, String name) {
        this.id = id;
        this.name = name;
    }
    public Student(int id, String name, int age, String emailAddress) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.emailAddress = emailAddress;
    }
    public static void save(Student partialUpdate, String id) {
        partialUpdate.setName(id);
    }
    public void setId(int id) {
        this.id = id;
    }
    public void setName(String name) {
        this.name = name;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public void setEmailAddress(String emailAddress) {
        this.emailAddress = emailAddress;
    }
    public int getId() {
        return id;
    }
    public String getName() {
        return name;
    }
    public int getAge() {
        return age;
    }
    public String getEmailAddress() {
        return emailAddress;
    }
}

【问题讨论】:

    标签: java spring spring-boot jpa patch


    【解决方案1】:

    未来的最佳解决方案是在您的应用程序中添加一个 DTO 层,并使用它来映射到您的对象。请参见下面的示例。

    public class StudentDto {
        private String name;
    
        public void setName(String name) {
            this.name = name;
        }
        public String getName() {
            return name;
        }
    }
    

    然后您可以通过Mapstruct 将其映射到您的模型:

    @Mapper
    public abstract class StudentMapper {
        public static final StudentMapper INSTANCE = 
        Mappers.getMapper(StudentMapper.class);
          
        @Mapping
        Student studentDtoToStudent(StudentDto studentDto); 
    }
    

    Mapstruct 依赖项:

    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct-jdk8</artifactId>
        <version>1.3.0.Final</version>
    </dependency>
    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct-processor</artifactId>
        <version>1.3.0.Final</version>
    </dependency>
    

    您将能够向外界隐藏您的内部结构。
    在您的控制器中:

    public ResponseEntity partialUpdateName(
        @RequestBody StudentDto partialUpdate, 
        @PathVariable("id") String id)
    {
        Student student = 
        StudentMapper.INSTANCE.studentDtoToStudent(partialUpdate);
    }
    

    最后一行将为您提供一个安全的学生模型,然后您可以保存它

    1. 快速解决方案 在您的控制器中:
    public ResponseEntity partialUpdateName(
        @RequestBody Student partialUpdate, 
        @PathVariable("id") String id) 
    {
        Optional<Student> optionalStudent = repository.findById(id);
    
        if(optionalStudent.isPresent() && partialUpdate!=null) {
            Student current=optional.get();
            current.setName(partialUpdate.getName());
            return ResponseEntity.ok(repository.save(current));     
         }  
                  
         /* return an error */
    }
    

    【讨论】:

    • @Mapper 很好,但我在映射时出错。不知道为什么?
    • 我用一个快速的解决方案更新了我的答案,你可以看看哪个更适合你。如果您使用第二个选项,请不要添加模型,只需更改代码以添加我在快速解决方案部分中提到的代码 sn-p,但如果您正在构建生产代码,我建议您使用第一个选项。
    • 感谢您的回答。这是一个错误“@Mapping”不适用于映射注释的方法
    • 请添加我在回答您的 pom.xml 时提到的两个依赖项。
    • 我在我的 Gradle 上添加了依赖项,但仍然有一个错误,例如“target”缺少通​​过 required
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-23
    • 2015-05-25
    • 2017-03-09
    • 2021-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多