在更新數據時,有時候咱們只須要更新一部分字段,其餘字段保持不變。Spring Data JPA並未提供現成的接口,直接使用save()更新會致使其餘字段被Null覆蓋掉。java
一般有兩種方法解決此問題:sql
代碼以下:數據庫
public FrontResult update(Evaluation evaluation) { // 從數據庫中獲取對象 Evaluation original = evaluationRepo().findById(evaluation.getId()); // 複製想要更改的字段值 BeanUtils.copyProperties(evaluation, original, getNullPropertyNames(evaluation)); // 更新操做 evaluationRepo().save(original); return FrontResult.init(FrontResult.SUCCEED, "更新成功"); }
使用的工具類以下(用於獲取未被修改的字段名): app
public class UpdateUtil { public static String[] getNullPropertyNames(Object source) { final BeanWrapper src = new BeanWrapperImpl(source); java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors(); Set<String> emptyNames = new HashSet<>(); 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); } }
注意:工具
在執行update或者delete方法時,必須加上註解@Modifying 和 @Transactional。lua
spa
代碼以下:code
@Modifying @Transactional @Query("update Test a set " + "a.name = CASE WHEN :#{#testAre.name} IS NULL THEN a.name ELSE :#{#testAre.name} END ," + "a.age = CASE WHEN :#{#testAre.age} IS NULL THEN a.age ELSE :#{#testAre.age} END ," + "a.insertTime = CASE WHEN :#{#testAre.insertTime} IS NULL THEN a.insertTime ELSE :#{#testAre.insertTime} END ," + "a.spare = CASE WHEN :#{#testAre.spare} IS NULL THEN a.spare ELSE :#{#testAre.spare} END " + "where a.id = :#{#testAre.id}") int update(@Param("testAre") TestAre testAre);
對象