一尘不染

如何在Spring Data中精美地更新JPA实体?

spring

因此,我查看了有关使用Spring Data的JPA的各种教程,并且在许多场合都做了不同的事情,而且我不确定哪种正确的方法是正确的。

假设存在以下实体:

package stackoverflowTest.dao;

import javax.persistence.*;

@Entity
@Table(name = "customers")
public class Customer {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private long id;

@Column(name = "name")
private String name;

public Customer(String name) {
    this.name = name;
}

public Customer() {
}

public long getId() {
    return id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}
}

我们还有一个DTO,该DTO在服务层中检索,然后移交给控制器/客户端。

package stackoverflowTest.dto;

public class CustomerDto {

private long id;
private String name;

public CustomerDto(long id, String name) {
    this.id = id;
    this.name = name;
}

public long getId() {
    return id;
}

public void setId(long id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}
}

因此,现在假设客户要在Webui中更改其名称-然后将执行一些控制器操作,在该操作中将有带有旧ID和新名称的更新的DTO。

现在,我必须将此更新的DTO保存到数据库中。

不幸的是,目前无法更新现有客户(除了删除数据库中的条目并使用新的自动生成的ID创建新的Cusomter外)

但是,由于这是不可行的(特别是考虑到这样的实体可能具有数百个关系),因此我想到了两种简单的解决方案:

  1. 在Customer类中为ID设置一个设置器-从而允许设置ID,然后通过相应的存储库保存Customer对象。
    要么

  2. 将id字段添加到构造函数中,每当你要更新客户时,总会创建一个具有旧ID的新对象,但使用其他字段的新值(在这种情况下,仅是名称)
    所以我的问题是,是否有一个一般规则该如何做?我所解释的两种方法的弊端可能是什么?


阅读 591

收藏
2020-04-19

共1个答案

一尘不染

甚至更好@Tanjim Rahman回答,你可以使用Spring Data JPA使用该方法 T getOne(ID id)

Customer customerToUpdate = customerRepository.getOne(id);
customerToUpdate.setName(customerDto.getName);
customerRepository.save(customerToUpdate);

更好,因为getOne(ID id) 仅使你获得引用(代理)对象,而不从数据库中获取它。在此参考上,你可以设置所需的内容,save()并且将仅执行你期望的SQL UPDATE语句。find()相比之下,当你像@Tanjim Rahmans这样的方式调用时,spring数据JPA将执行SQL SELECT,以在刚更新时从DB物理上获取你不需要的实体。

2020-04-19