covenlonki 发表于 2023-8-10 18:31

java对象实体类属性字段对比变化过程

java对象实体类属性字段对比变化过程


package com.covenlonki.utils;



/**

* 对比结果

*/

public class ComparedResult {



    /**

   * 对比字段名称

   */

    private String fieldName;



    /**

   * 对比

   */

    private String compare;



    public String getFieldName() {

      return fieldName;

    }



    public void setFieldName(String fieldName) {

      this.fieldName = "【" + fieldName + "】";

    }



    public String getCompare() {

      return compare;

    }



    public void setCompare(String compare) {

      this.compare = compare;

    }

   

    @Override

    public String toString() {

      return "ComparedResult{" +

                "fieldName='" + fieldName + '\'' +

                ", compare='" + compare + '\'' +

                '}';

    }

}





package com.covenlonki.utils;

import io.swagger.annotations.ApiModelProperty;

import lombok.Data;

import java.util.Date;

import java.util.Objects;



/**

* 对比实体类

*/

@Data

public class ComparedEntity {



    @ApiModelProperty(name = "姓名")

    public String name;



    @ApiModelProperty(name = "年龄")

    private Integer age;



    @ApiModelProperty(name = "修改人ID")

    private Integer modifyUserId;



    @ApiModelProperty(name = "修改人姓名")

    private String modifyUserName;



    @ApiModelProperty(name = "修改时间")

    private Date modifyTime;



    public ComparedEntity() {

    }



    public ComparedEntity(String name, Integer age) {

      this.name = name;

      this.age = age;

    }



    @Override

    public boolean equals(Object o) {

      if (this == o) return true;

      if (o == null || getClass() != o.getClass()) return false;

      ComparedEntity that = (ComparedEntity) o;

      return Objects.equals(name, that.name) && Objects.equals(age, that.age) && Objects.equals(modifyUserId, that.modifyUserId) && Objects.equals(modifyUserName, that.modifyUserName) && Objects.equals(modifyTime, that.modifyTime);

    }



    @Override

    public int hashCode() {

      return Objects.hash(name, age, modifyUserId, modifyUserName, modifyTime);

    }



    @Override

    public String toString() {

      return "ComparedEntity{" +

                "name='" + name + '\'' +

                ", age=" + age +

                ", modifyUserId=" + modifyUserId +

                ", modifyUserName='" + modifyUserName + '\'' +

                ", modifyTime=" + modifyTime +

                '}';

    }

}





package com.covenlonki.utils;

import cn.hutool.json.JSONUtil;

import io.swagger.annotations.ApiModelProperty;

import java.beans.PropertyDescriptor;

import java.lang.reflect.Field;

import java.lang.reflect.Method;

import java.util.ArrayList;

import java.util.Arrays;

import java.util.List;

import java.util.stream.Collectors;



/**

* 对比工具

*/

public class ComparedUtil {



    public static void main(String[] args) {

      ComparedEntity u1=new ComparedEntity();

      u1.setName("李师");

      u1.setAge(18);

      u1.setModifyUserName("admin");

      u1.setModifyUserId(666);



      ComparedEntity u2=new ComparedEntity();

      u2.setName("李师22");

      u2.setAge(20);

      u2.setModifyUserName("covenlonki");

      u2.setModifyUserId(888);



      List<ComparedResult> comparedResults = compareTwoObject(u1, u2);

      String s = JSONUtil.toJsonStr(comparedResults);

      System.out.println(s);

    }



    /**

   * 比较新旧对象内容是否有变化

   * @Param oldObject 旧对象

   * @param newObject 新对象

   * @Return 结果

   */

    private static List<ComparedResult> compareTwoObject(ComparedEntity oldObject, ComparedEntity newObject) {

      List<ComparedResult> ret=new ArrayList<>();

      Class clazz =oldObject.getClass();



      try {

            // 获取所有字段

            Field[] Fields = clazz.getDeclaredFields();

            for (Field field : Fields) {

                String fieldName = field.getName();// 字段名

                if (fieldName.equals("modifyUserId") || fieldName.equals("modifyUserName") || fieldName.equals("modifyTime")) {

                  continue;

                }

                ApiModelProperty fieldAnon =field.getAnnotation(ApiModelProperty.class);

                String filedAnoName="";

                if(null!= fieldAnon){

                  filedAnoName= fieldAnon.name(); // 字段中文名称

                }



                PropertyDescriptor pd=new PropertyDescriptor(field.getName(),clazz);

                Method getMethod=pd.getReadMethod();



                // 在oldObject上调用get方法等同于获得oldObject的属性值

                Object oldValue = getMethod.invoke(oldObject);

                // 在newObject上调用get方法等同于获得newObject的属性值

                Object newValue = getMethod.invoke(newObject);



                // 对比两个值是否一致

                if(!oldValue.equals(newValue)){

                  ComparedResult result=new ComparedResult();

                  result.setFieldName(filedAnoName);

                  result.setCompare(oldValue + " -> " + newValue);

                  ret.add(result);

                }

            }



      } catch (Exception e) {

            e.printStackTrace();

      }



      return ret;

    }



    /**

   * 比较值是否相等

   *

   * @param newValue 新值

   * @param oldValue 旧值

   * @return 相等 返回true

   */

    private static boolean compareTwo(Object newValue, Object oldValue) {

      // 如果两字段都为空,也认为相等(用==判断,不得用equals)

      if (oldValue == null || newValue == null) {

            return true;

      }

      if (oldValue == null && newValue == "") {

            return true;

      }

      // 比较内容

      if (newValue.equals(oldValue)) {

            return true;

      }

      return false;

    }

}



运行结果:

[{"fieldName":"【姓名】","compare":"李师 -> 李师22"},{"fieldName":"【年龄】","compare":"18 -> 20"}]




比较对象实体类属性字段对比变化过程,可用于数据库更新数据时,比较数据,当数据发生变化时才更新数据库,或者记录已经变更的数据 等等.....

xiaoniba1028 发表于 2023-8-10 20:18

非常不错哦

19sl 发表于 2023-8-10 21:27

很有用哦

moruye 发表于 2023-8-10 21:58

jushuaishuai 发表于 2023-8-11 08:53

现在mybatis-plus对更新时,没有变动或者没有传值的字段是不会更新的,已经处理的不错了,你这个就需要先从数据库查一遍,然后再和传入的值进行比较吗?一查一更新,两次数据库操作,会不会对影响性能,当然这个做法非常稳健。

covenlonki 发表于 2023-8-11 15:02

jushuaishuai 发表于 2023-8-11 08:53
现在mybatis-plus对更新时,没有变动或者没有传值的字段是不会更新的,已经处理的不错了,你这个就需要先从 ...

都是主键id查询的话影响不大,影响可以忽略,

chen180 发表于 2023-8-29 15:31

挺有想法,借鉴了。感谢
页: [1]
查看完整版本: java对象实体类属性字段对比变化过程