Spring Data JPA 更新方法

10

我仍在寻找Spring Data JPA中的更新方法,以更新关系数据库中保存的给定对象。 我只发现强制通过@Query注释(与@Modifying相比)指定某种UPDATE查询的解决方案,例如:

@Modifying
@Query("UPDATE User u SET u.firstname = ?1, u.lastname = ?2 WHERE u.id = ?3")
public void update(String firstname, String lastname, int id);

为了构建查询,我还需要单个参数而不是 整个对象。但这正是我想要做的(传递整个对象)。

因此,我正在寻找这样的方法:

public void update(Object obj);

能否基于Spring Data JPA构建这样的更新方法?如何进行注释?

谢谢!


(T)
3个回答

17
如果目标是修改一个实体,您不需要任何更新方法。您可以从数据库中获取对象,对其进行修改,JPA 会自动保存:
User u = repository.findOne(id);
u.setFirstName("new first name");
u.setLastName("new last name");
如果您有一个已分离的实体并想要合并它,则使用 CrudRepositorysave() 方法:
User attachedUser = repository.save(detachedUser);

如果我正在使用findALL(),我需要为每个用户循环并进行多次保存调用吗? - Arpit Agarwal
@ArpitAgarwal 如果你在一个 @Transactional 中,选择所有实体后进行修改就足够了,不需要显式调用 .save().saveAll(),除非你有任何已分离的实体(例如,从数据库中未选择或手动分离的实体)。事务结束时会更新每个实体。 - buræquete
@JB Nizet - 这会更新整个实体(覆盖整个实体),还是只会更新更改的值。 - PAA
这个解决方案很好。但是要小心,它会更新所有列(即使是未更改的列),这可能是昂贵或危险的! - SpongeBob

0

这些答案没有解决问题,即如何避免所有混乱...

if (var1 != null) u.setVar1( var1 );
if (var2 != null) u.setVar2( var2 );
....
if (varN != null) u.setVarN( varN );

胡闹。

因此,本质上,问题涉及如何合并对象。不幸的是,JPA“合并”是一个误称。它是重新附加一个分离的对象。

您尝试使用这个方案了吗:

  1. 添加jackson数据绑定依赖项
  2. 将更新对象(源)转换为Map

Map<String,Object> sourceMap = objMapper.convertValue(source,Map.class);

  1. 使用Java 8流删除空值
  2. 像上面一样将要更新的对象(目标到Map)转换
  3. 使用新的Java 8 Map合并方法将源更新到目标中,即

targetMap.merge(...);

  1. 然后使用objMapper将targetMap转换回目标类型。

一个警告,现在你有一个更新的实体,它不是JPA-attached,所以你必须做一个target.merge();


0

如果您要更新一个实体,不需要使用JPQL查询(可选)。您可以直接使用(旧版本)findOne或(新版本)findById来访问数据并进行所需的修改。

例如- 这里批准(实体)已更新。

Optional<User> user= Repository.findById(id);
Registration reg = reg.get();       
reg.setApproved("yes");
userRepo.save(reg);

就是这样了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接