已解决
Java对比对象修改前与修改后字段发生的变化
来自网友在路上 180880提问 提问时间:2023-09-23 04:12:11阅读次数: 80
最佳答案 问答题库808位专家为你答疑解惑
- 开发过程中,我们通常会对系统操作人对系统的操作进行记录,记录操作前后某个字段的变化,如下图
2. 提供一个工具类,可以比较一个对象里面,源对象,与修改后的对象,有哪些字段发生了改变, 第一步
/*** @author qiankun.hu* @version 1.0.0* @createTime 2023年09月20日 17:00:00* @Description TODO*/
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ColumnInfo {/*** 字段code*/String columnCode() default "";/*** 字段名称*/String columnName() default "";/*** 字段类型*/String columnType() default "";
}
工具类代码
import com.example.demo.config.ColumnInfo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.Timestamp;
import java.util.*;/*** @author qiankun.hu* @version 1.0.0* @createTime 2023年09月20日 17:00:00* @Description TODO*/
public class MyBeanUtils extends BeanUtils {/*** 比较两个实体属性值,返回一个map以有差异的属性名为key,value为一个list分别存obj1,obj2此属性名的值** @param obj1 源值* @param obj2 最新值* @param ignoreArr 选择忽略比较的属性数组* @return 属性差异比较结果map* <p>* 后面考虑添加注解字段名和中文名称,已达到提示对应的中文信息*/public static Map<String, List<Object>> compareFields(Object obj1, Object obj2, String[] ignoreArr) {try {Map<String, List<Object>> map = new HashMap<String, List<Object>>();List<String> ignoreList = null;if (ignoreArr != null && ignoreArr.length > 0) {// array转化为listignoreList = Arrays.asList(ignoreArr);}if (obj1 == null) {Class clazz = obj2.getClass();// 获取object的属性描述PropertyDescriptor[] pds = Introspector.getBeanInfo(clazz,Object.class).getPropertyDescriptors();// 这里就是所有的属性了for (PropertyDescriptor pd : pds) {// 属性名String name = pd.getName();// 如果当前属性选择忽略比较,跳到下一次循环if (ignoreList != null && ignoreList.contains(name)) {continue;}// Field field = clazz.getDeclaredField(name);Field field;try {field = clazz.getDeclaredField(name);} catch (NoSuchFieldException e) {try {//此处用于解决继承导致的getDeclaredField不能直接获取父类属性的问题field = clazz.getSuperclass().getDeclaredField(name);} catch (NoSuchFieldException ee) {//此处用于解决继承导致的getDeclaredField不能直接获取父类属性的问题field = clazz.getSuperclass().getSuperclass().getDeclaredField(name);}}ColumnInfo columnInfo = field.getAnnotation(ColumnInfo.class);if (columnInfo != null) {String columName = columnInfo.columnName();String columnCode = columnInfo.columnCode();String columnType = columnInfo.columnType();name = name + "_" + columName + "_" + columnCode + "_" + columnType;} else {continue;}// get方法Method readMethod = pd.getReadMethod();Object o2 = readMethod.invoke(obj2);if (o2 != null) {List<Object> list = new ArrayList<Object>();list.add(null);list.add(o2);map.put(name, list);}}} else {// 只有两个对象都是同一类型的才有可比性if (obj1.getClass() == obj2.getClass()) {Class clazz = obj1.getClass();// 获取object的属性描述PropertyDescriptor[] pds = Introspector.getBeanInfo(clazz,Object.class).getPropertyDescriptors();// 这里就是所有的属性了for (PropertyDescriptor pd : pds) {// 属性名String name = pd.getName();// 如果当前属性选择忽略比较,跳到下一次循环if (ignoreList != null && ignoreList.contains(name)) {continue;}//Field field = clazz.getDeclaredField(name);Field field;try {field = clazz.getDeclaredField(name);} catch (NoSuchFieldException e) {try {//此处用于解决继承导致的getDeclaredField不能直接获取父类属性的问题field = clazz.getSuperclass().getDeclaredField(name);} catch (NoSuchFieldException ee) {//此处用于解决继承导致的getDeclaredField不能直接获取父类属性的问题field = clazz.getSuperclass().getSuperclass().getDeclaredField(name);}}ColumnInfo columnInfo = field.getAnnotation(ColumnInfo.class);if (columnInfo != null) {String columName = columnInfo.columnName();String columnCode = columnInfo.columnCode();String columnType = columnInfo.columnType();name = name + "_" + columName + "_" + columnCode + "_" + columnType;} else {continue;}// get方法Method readMethod = pd.getReadMethod();// 在obj1上调用get方法等同于获得obj1的属性值Object o1 = readMethod.invoke(obj1);// 在obj2上调用get方法等同于获得obj2的属性值Object o2 = readMethod.invoke(obj2);if (o1 instanceof Timestamp) {o1 = new Date(((Timestamp) o1).getTime());}if (o2 instanceof Timestamp) {o2 = new Date(((Timestamp) o2).getTime());}if (o1 == null && o2 == null) {continue;} else if (o1 == null && o2 != null) {List<Object> list = new ArrayList<Object>();list.add(o1);list.add(o2);if (o2 instanceof String && StringUtils.isBlank(String.valueOf(o2))) {o2 = null;}if (o2 != null) {map.put(name, list);}continue;}// 比较这两个值是否相等,不等就可以放入map了if (!o1.equals(o2)) {List<Object> list = new ArrayList<Object>();list.add(o1);list.add(o2);if(o2!=null){o1 = o1 instanceof String && StringUtils.isBlank(String.valueOf(o1)) ? "" : o1;Object info = (o2 instanceof String && StringUtils.isBlank(String.valueOf(o2)) ? "" : o2);o2 = o2 == null ? "" : info;if(!o1.equals(o2)){map.put(name, list);}}}}}}return map;} catch (Exception e) {return null;}}
}
3 进行测试
import com.alibaba.fastjson.JSON;
import com.example.demo.config.ColumnInfo;
import com.example.demo.util.MyBeanUtils;
import java.util.*;/*** @author qiankun.hu* @version 1.0.0* @createTime 2022年10月14日 13:35:00* @Description TODO*/
public class StudentDto {@ColumnInfo(columnCode = "name", columnName = "名称")private String name;@ColumnInfo(columnCode = "name", columnName = "名称")private String age;@ColumnInfo(columnCode = "studentNum", columnName = "学号")private Integer studentNum;@ColumnInfo(columnCode = "classNum", columnName = "班级号")private String classNum;public static void main(String[] args) {//老数据StudentDto s1 = new StudentDto();s1.setName("张三");s1.setAge("18");s1.setStudentNum(9001);s1.setClassNum("高一二班");//修改后的数据StudentDto s2 = new StudentDto();s2.setName("张三");s2.setAge("19");s2.setStudentNum(9002);s2.setClassNum("高一三班");//忽略对比的字段String[] arr = new String[1];arr[0] = "studentNum";//对比哪些字段发生改变,K 是发生改变的字段 value 是字段前后的变化Map<String, List<Object>> stringListMap = MyBeanUtils.compareFields(s1, s2, null);System.out.println( JSON.toJSONString(stringListMap) );}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAge() {return age;}public void setAge(String age) {this.age = age;}public Integer getStudentNum() {return studentNum;}public void setStudentNum(Integer studentNum) {this.studentNum = studentNum;}public String getClassNum() {return classNum;}public void setClassNum(String classNum) {this.classNum = classNum;}
}
输出结果如下:
{
"age_名称_name_": ["18", "19"],
"studentNum_学号_studentNum_": [9001, 9002],
"classNum_班级号_classNum_": ["高一二班", "高一三班"]
}
我们可以看到,对象修改后与修改后,相关字段产生的变化,如果有不需要对比的字段,传入相同的参数既可
查看全文
99%的人还看了
相似问题
- SpringBoot使用ObjectMapper之Long和BigDemical类型的属性字符串处理,防止前端丢失数值精度
- 〖大前端 - 基础入门三大核心之JS篇㊲〗- DOM改变元素节点的css样式、HTML属性
- QT中样式表常见属性与颜色的设置与应用
- Java继承中的属性名相同但是类型不同的情况
- C#开发的OpenRA游戏之属性QuantizeFacingsFromSequence(7)
- XmlElement注解在Java的数组属性上,以产生多个相同的XML元素
- CSS-列表属性篇
- CSS 文本属性篇
- 计算属性与watch的区别,fetch与axios在vue中的异步请求,单文本组件使用,使用vite创建vue项目,组件的使用方法
- JAXB:用XmlElement注解复杂类型的Java属性,来产生多层嵌套的xml元素
猜你感兴趣
版权申明
本文"Java对比对象修改前与修改后字段发生的变化":http://eshow365.cn/6-11880-0.html 内容来自互联网,请自行判断内容的正确性。如有侵权请联系我们,立即删除!