gpt4 book ai didi

java - JPA:仅更新特定字段

转载 作者:IT老高 更新时间:2023-10-28 13:03:14 33 4
gpt4 key购买 nike

有没有办法使用 Spring Data JPA 中的方法 save 更新实体对象的仅某些字段

例如,我有一个这样的 JPA 实体:

@Entity
public class User {

@Id
private Long id;

@NotNull
private String login;

@Id
private String name;

// getter / setter
// ...
}

使用它的 CRUD repo :

public interface UserRepository extends CrudRepository<User, Long> { }

Spring MVC 中,我有一个 Controller ,它获取一个 User 对象来更新它:

@RequestMapping(value = "/rest/user", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public ResponseEntity<?> updateUser(@RequestBody User user) {

// Assuming that user have its id and it is already stored in the database,
// and user.login is null since I don't want to change it,
// while user.name have the new value

// I would update only its name while the login value should keep the value
// in the database
userRepository.save(user);

// ...
}

我知道我可以使用 findOne 加载用户,然后更改其名称并使用 save 更新它...但是如果我有 100 个字段并且我想更新其中的 50 个,更改每个值可能会非常烦人..

有没有办法告诉类似“保存对象时跳过所有空值”?

最佳答案

我也有同样的问题,正如 M. Deinum 指出的那样,答案是否定的,你不能使用保存。主要问题是 Spring Data 不知道如何处理空值。 null值是没有设置还是因为需要删除才设置?

现在从你的问题来看,我想你也有和我一样的想法,那就是 save 可以让我避免手动设置所有更改的值。

那么有没有可能避免所有的手动映射呢?好吧,如果您选择遵守 null 始终表示“未设置”的约定并且您拥有原始模型 ID,那么可以。您可以使用 Springs BeanUtils 自己避免任何映射。

您可以执行以下操作:

  1. 读取现有对象
  2. 使用 BeanUtils 复制值
  3. 保存对象

现在,Spring 的 BeanUtils 实际不支持不复制 null 值,因此它将覆盖现有模型对象上未设置为 null 的任何值。幸运的是,这里有一个解决方案:

How to ignore null values using springframework BeanUtils copyProperties?

所以把它们放在一起你最终会得到这样的东西

@RequestMapping(value = "/rest/user", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public ResponseEntity<?> updateUser(@RequestBody User user) {

User existing = userRepository.read(user.getId());
copyNonNullProperties(user, existing);
userRepository.save(existing);

// ...
}

public static void copyNonNullProperties(Object src, Object target) {
BeanUtils.copyProperties(src, target, getNullPropertyNames(src));
}

public static String[] getNullPropertyNames (Object source) {
final BeanWrapper src = new BeanWrapperImpl(source);
java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();

Set<String> emptyNames = new HashSet<String>();
for(java.beans.PropertyDescriptor pd : pds) {
Object srcValue = src.getPropertyValue(pd.getName());
if (srcValue == null) emptyNames.add(pd.getName());
}
String[] result = new String[emptyNames.size()];
return emptyNames.toArray(result);
}

关于java - JPA:仅更新特定字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27818334/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com