wake-up-neo.com

Spring Data JPA: Wie aktualisiere ich ein Modell elegant?

  1. Mein Model sieht so aus:

    @Entity
    @Table(name = "user")
    public class User {
    
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
    
        @Column(name="email")
        private String email;
    
        @Column(name = "weblink")
        private String webLink;
    
        //getter & setter
    }
    
  2. wir sammeln Formulare oder mobile Daten über eine http-Anfrage und springmvc wird diese Daten einem Model-ähnlichen Benutzer zur Verfügung stellen.

    zum Beispiel habe ich eine Anfrage wie diese:

    http://localhost:8080/update?id=1919&[email protected]

  3. in Contoller werden die Anforderungs-URL und ihre Parameter automatisch in ein User-Objekt übertragen.

    @RequestMapping(method = RequestMethod.GET, value = "/update0")
    public User update(@ModelAttribute("User") User user){
    
        System.out.println(user.getId());
        System.out.println(user.getEmail());
        System.out.println(user.getWebLink());
    
        return userRepository.save(test);
    }
    
  4. wenn ich einen Datensatz in MySQL habe, dessen ID 1919 ist, und die Spalten (ID, E-Mail, Weblik) alle Werte haben.

    wie Sie sehen, hat das Benutzerobjekt, das per Web oder Mobiltelefon übergeben wurde, zwei Eigenschaften

    http://localhost:8080/update?id=1919&[email protected]

    iD und E-Mail haben Werte und Weblink nicht.

    Wenn ich also die save-Methode ausführe, wird die Spalten-E-Mail auf [email protected] aktualisiert, und das Weblik-Feld wird ebenfalls auf NULL aktualisiert, aber ich möchte dieses Feld nicht aktualisieren, sondern nur das E-Mail-Feld aktualisieren.

  5. Ich habe zwei Möglichkeiten, um das Problem zu beheben, aber alle sind nicht elegant.

    5.1 Benutzerobjekt zuerst laden und aktualisieren

    User userExist = userRepository.findOne(user.getId());
    userExist.setEmail(user.getEmail());
    
    //or using 
    //BeanUtil.copyProprty(formDto,modle)
    
    userRepository.save();
    

    5.2 mit @DynamicUpdate, aber es funktioniert nicht.

    Gibt es eine andere Möglichkeit, das Benutzermodell zu aktualisieren und keine zusätzliche Arbeit zu leisten?.

    Danke im Voraus.

9
diligent

Der einfachste Weg ist eine entsprechend eingerichtete Controller-Methode:

@RequestMapping(value = "/users/{user}", method = RequestMethod.PATCH)
public … updateUser(@ModelAttribute User user) { … }

Gemäß der Referenzdokumentation wenn diese Methode aufgerufen wird, werden folgende Schritte ausgeführt:

  1. Eine Instanz von User muss abgerufen werden. Dies erfordert im Wesentlichen eine Converter von String bis User, die bei Spring MVC registriert werden muss, um das aus der URI-Vorlage extrahierte Pfadsegment in eine User zu konvertieren. Wenn Sie z. Wenn Sie Spring Data verwenden und dessen Websupport aktivieren, wie in der Referenzdokumentation beschrieben, funktioniert dies sofort.
  2. Nachdem die vorhandene Instanz abgerufen wurde, werden Anfragedaten an das vorhandene Objekt gebunden.
  3. Das gebundene Objekt wird der Methode übergeben.

Zusätzliche Hinweise

  • Verwenden Sie GET nicht als HTTP-Methode für Updates. GET ist als sicherer Vorgang (keine Nebenwirkungen) definiert, was ein Update nicht ist. PATCH ist hier die richtige Methode, da sie definiert ist, um eine teilweise Aktualisierung einer vorhandenen Ressource zu ermöglichen.
  • Um Formulardaten in PUT- und PATCH-Anforderungen zu übermitteln, müssen Sie eine HttpPutFormContentFilter mit der Anwendung wie hier registrieren. Ich habe eine Ausgabe mit Spring Boot eingereicht, um dies standardmäßig zu registrieren.
13
Oliver Drotbohm

Zuerst muss ich sagen, dass die Patch-Lösung von @Oliver Gierke wirklich großartig ist.

In meinem vorherigen Projekt lautet meine Lösung:
1. Erstellen Sie eine abstrakte Klasse, um JpaRepository zu implementieren, und implementieren Sie die Funktion save().
2. Rufen Sie in der Sicherungsfunktion die Entität aus der DB ab. Es gibt es nicht, speichern Sie es einfach. Verwenden Sie andernfalls Reflektion, um alle NOT NULL-Felder von der aktualisierten Entität abzurufen und von DB in Entität zu setzen. (es ist ähnlich wie du, aber ich habe es für alle Speicherfunktion gemacht)

0
Mavlarn