zoukankan      html  css  js  c++  java
  • 如何使用Sping Data JPA更新局部字段

    问题描述

    在更新数据时,有时候我们只需要更新一部分字段,其他字段保持不变。Spring Data JPA并未提供现成的接口,直接使用save()更新会导致其他字段被Null覆盖掉。

    解决办法

    通常有两种方法解决此问题:

    1、通过传入对象的id,从数据库中查询得到原始对象,然后将要修改的字段封装到原始对象中。再以封装后的对象为参数进行save()。

    代码如下:

    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, "更新成功");
        }
    

    使用的工具类如下(用于获取未被修改的字段名):

    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);
        }
    }
    

    2、通过注解@Query自己实现sql语句。

    注意:

    在执行update或者delete方法时,必须加上注解@Modifying 和 @Transactional。

    此处的Test要使用实体的类名,不是数据库中的表名。

    代码如下:

    @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);
    

    一般字段比较多时我会选第一种方式,虽然多查了一次数据库,但是省键盘。

  • 相关阅读:
    Java实现 LeetCode 69 x的平方根
    Java实现 LeetCode 68 文本左右对齐
    Java实现 LeetCode 68 文本左右对齐
    Java实现 LeetCode 68 文本左右对齐
    Java实现 LeetCode 67 二进制求和
    Java实现 LeetCode 67 二进制求和
    Java实现 LeetCode 67 二进制求和
    Java实现 LeetCode 66 加一
    Java实现 LeetCode 66 加一
    CxSkinButton按钮皮肤类
  • 原文地址:https://www.cnblogs.com/hanstrovsky/p/11867878.html
Copyright © 2011-2022 走看看