因此,我查看了有关使用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外)
但是,由于这是不可行的(特别是考虑到这样的实体可能具有数百个关系),因此我想到了两种简单的解决方案:
在Customer类中为ID设置一个设置器-从而允许设置ID,然后通过相应的存储库保存Customer对象。 要么
将id字段添加到构造函数中,每当你要更新客户时,总会创建一个具有旧ID的新对象,但使用其他字段的新值(在这种情况下,仅是名称) 所以我的问题是,是否有一个一般规则该如何做?我所解释的两种方法的弊端可能是什么?
甚至更好@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物理上获取你不需要的实体。
getOne(ID id)
save()
find()