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

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

  • 相关阅读:
    python学习笔记(六)---文件操作与异常处理机制
    python学习笔记(五)---函数与类
    python学习笔记(四)---用户输入与while循环
    python学习笔记(三)---字典
    python学习笔记(二)---for循环与操作列表
    python学习笔记(一)---字符串与列表
    HTML
    80386汇编
    8086汇编语言
    网络设备配置--2、通过交换机划分vlan
  • 原文地址:https://www.cnblogs.com/hanstrovsky/p/11867878.html
Copyright © 2011-2022 走看看