如何在 Spring Data 中漂亮地更新 JPA 实体?

2022-01-18 00:00:00 spring java jpa spring-data spring-data-jpa

因此,我查看了有关使用 Spring Data 的 JPA 的各种教程,并且在很多情况下都做了不同的处理,我不太确定正确的方法是什么.

So I have looked at various tutorials about JPA with Spring Data and this has been done different on many occasions and I am no quite sure what the correct approach is.

假设存在以下实体:

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,它在服务层中检索,然后交给控制器/客户端.

We also have a DTO which is retrieved in the service layer and then handed to the controller/client side.

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 中更改他的名字 - 然后会有一些控制器操作,其中将有更新的 DTO 与旧 ID 和新名称.

So now assume the Customer wants to change his name in the webui - then there will be some controller action, where there will be the updated DTO with the old ID and the new name.

现在我必须将这个更新的 DTO 保存到数据库中.

Now I have to save this updated DTO to the database.

不幸的是,目前没有办法更新现有客户(除了删除数据库中的条目并使用新的自动生成的 id 创建一个新的客户)

Unluckily currently there is no way to update an existing customer (except than deleting the entry in the DB and creating a new Cusomter with a new auto-generated id)

但是由于这是不可行的(特别是考虑到这样的实体可能有数百个关系) - 所以我想到了 2 个直截了当的解决方案:

However as this is not feasible (especially considering such an entity could have hundreds of relations potentially) - so there come 2 straight forward solutions to my mind:

  1. 为 Customer 类中的 id 创建一个设置器 - 从而允许设置 id,然后通过相应的存储库保存 Customer 对象.

  1. 将 id 字段添加到构造函数中,每当您想更新客户时,您总是使用旧 id 创建一个新对象,但其他字段的新值(在这种情况下只有名称)

所以我的问题是是否有一般规则如何做到这一点?我解释的两种方法的缺点是什么?

So my question is wether there is a general rule how to do this? Any maybe what the drawbacks of the 2 methods I explained are?

推荐答案

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

Even better then @Tanjim Rahman answer you can using Spring Data JPA use the method 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 data JPA 将执行 SQL SELECT 以从数据库中物理获取实体,当您只是更新时,您不需要.

Is's better because getOne(ID id) gets you only a reference (proxy) object and does not fetch it from the DB. On this reference you can set what you want and on save() it will do just an SQL UPDATE statement like you expect it. In comparsion when you call find() like in @Tanjim Rahmans answer spring data JPA will do an SQL SELECT to physically fetch the entity from the DB, which you dont need, when you are just updating.

相关文章