1. import java.beans.Introspector;
    2. import java.beans.PropertyDescriptor;
    3. import java.lang.reflect.Method;
    4. import java.util.Date;
    5. import java.util.HashMap;
    6. import java.util.Map;
    7. import org.slf4j.Logger;
    8. import org.slf4j.LoggerFactory;
    9. import org.springframework.util.CollectionUtils;
    10. /**
    11. * 对象属性值比较工具
    12. * @author XueYQ
    13. * @date: 2020年8月3日
    14. */
    15. public class ObjectCompareUtil {
    16. private static Logger log = LoggerFactory.getLogger(ObjectCompareUtil.class);
    17. /**
    18. * 比较两个实体属性值,返回一个boolean,true则表时两个对象中的属性值无差异
    19. * @param oldObject 进行属性比较的对象1
    20. * @param newObject 进行属性比较的对象2
    21. * @return 属性差异比较结果boolean【true:无差异;false:有差异】
    22. */
    23. public static boolean compareObject(Object oldObject, Object newObject) {
    24. boolean isCompare = true;
    25. Map<String, Map<String,Object>> resultMap = compareFields(oldObject,newObject);
    26. if (!CollectionUtils.isEmpty(resultMap)) {
    27. isCompare = false;
    28. }
    29. return isCompare;
    30. }
    31. /**
    32. * 比较两个实体属性值,返回一个map以有差异的属性名为key,value为一个Map分别存oldObject,newObject此属性名的值
    33. * @param oldObject 进行属性比较的对象1
    34. * @param newObject 进行属性比较的对象2
    35. * @return 属性差异比较结果map
    36. */
    37. @SuppressWarnings("rawtypes")
    38. public static Map<String, Map<String,Object>> compareFields(Object oldObject, Object newObject) {
    39. Map<String, Map<String, Object>> map = new HashMap<String, Map<String,Object>>(16);
    40. try {
    41. /**
    42. * 只有两个对象都是同一类型的才有可比性
    43. */
    44. if (oldObject.getClass() == newObject.getClass()) {
    45. Class clazz = oldObject.getClass();
    46. // 获取object的所有属性
    47. PropertyDescriptor[] pds = Introspector.getBeanInfo(clazz, Object.class).getPropertyDescriptors();
    48. for (PropertyDescriptor pd : pds) {
    49. // 遍历获取属性名
    50. String name = pd.getName();
    51. // 获取属性的get方法
    52. Method readMethod = pd.getReadMethod();
    53. // 在oldObject上调用get方法等同于获得oldObject的属性值
    54. Object oldValue = readMethod.invoke(oldObject);
    55. // 在newObject上调用get方法等同于获得newObject的属性值
    56. Object newValue = readMethod.invoke(newObject);
    57. // 对象值为空,跳过
    58. if (oldValue == null || newValue == null) {
    59. break;
    60. }
    61. // 时间格式不比较,跳过
    62. if (oldValue instanceof Date || newValue instanceof Date) {
    63. break;
    64. }
    65. if (!oldValue.equals(newValue)) {
    66. // 比较这两个值是否相等,不等就可以放入map了
    67. Map<String, Object> valueMap = new HashMap<String,Object>(16);
    68. valueMap.put("oldValue",oldValue);
    69. valueMap.put("newValue",newValue);
    70. map.put(name, valueMap);
    71. }
    72. }
    73. }
    74. } catch(Exception e) {
    75. log.error("比较两个实体属性值出错;error={}", e.getMessage());
    76. }
    77. return map;
    78. }
    79. }