在Spring JPA中,经常看到这样的实体更新的实现:
@Transactional
public User updateUser(Long userId, String newName, String newEmail) {
User user = userRepository.findById(userId).orElseThrow(() -> new EntityNotFoundException("User not found"));
user.setName(newName);
user.setEmail(newEmail);
return userRepository.save(user);
}
在这里,我们使用 SELECT 语句获取实体,然后更新它。
另一种解决方案是直接更新实体:
@Transactional
public void updateUser(Long userId, String newName, String newEmail) {
int updatedRows = userRepository.updateEmailAndName(userId, newName, newEmail);
if (updatedRows == 0) {
throw new EntityNotFoundException("User not found");
}
}
存储库代码:
public interface UserRepository extends JpaRepository<User, Long> {
@Modifying
@Query("update User u set u.name = ?2, u.email = ?3 where u.id = ?1")
int updateEmailAndName(Long id, String newName, String newEmail);
}
所以,我的问题是,第一个解决方案不是反模式吗?
第一个不是反模式。两种方法都是正确的,并且取决于上下文和代码风格。通常,由于代码可读性,第一个最常用,并且更适合测试目的。
如果您使用第二个,在某些情况下您将需要
@Modifying(clearAutomatically = true)
来保留后续操作的更改。您可以了解更多信息这里。
因此,请根据您的需求和团队标准使用最佳方法。