反射实现实体对比,根据需要对比字段进行对比

反射实现实体对比,根据需要对比字段进行对比

使用反射获取实体对象方法和值

import lombok.extern.slf4j.Slf4j;

import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.sql.Timestamp;
import java.util.*;

@Slf4j
public class CompareEntityFiled {

/**
 *COY 实体类对比
 * @param newEntity
 * @param oldEntity
 * @param compareList
 * @param filedInfo
 * @return
 */
public static Map<String, List<Object>> compareFields(Object newEntity, Object oldEntity, List<String> compareList,Map<String,String> filedInfo) {
    try {

        Map<String, List<Object>> map = new HashMap<String, List<Object>>();

        // 只有两个对象都是同一类型的才有可比性
        if (newEntity.getClass() == oldEntity.getClass()) {
            Class clazz = newEntity.getClass();
            // 获取object的属性描述
            PropertyDescriptor[] pds = Introspector.getBeanInfo(clazz,
                    Object.class).getPropertyDescriptors();
            // 属性对比
            for (PropertyDescriptor pd : pds) {
                // 属性名
                String name = pd.getName();
                // 是否当前属性选择进行比较,否跳到下一次循环
                if (compareList != null && compareList.contains(name)) {
                    // get方法
                    Method readMethod = pd.getReadMethod();
                    // 在objBefore上调用get方法等同于获得objBefore的属性
                    Object objBefore = readMethod.invoke(newEntity);
                    // 在objAfter上调用get方法等同于获得objAfter的属性值
                    Object objAfter = readMethod.invoke(oldEntity);

                    //如果是日期类型需要转化成时间戳
                    if (objBefore instanceof Timestamp) {
                        objBefore = new Date(((Timestamp) objBefore).getTime());
                    }
                    if (objAfter instanceof Timestamp) {
                        objAfter = new Date(((Timestamp) objAfter).getTime());
                    }

                    //判断开始
                    if (objBefore == null && objAfter == null) {
                        continue;
                    } else if (objBefore == null && objAfter != null) {
                        List<Object> list = new ArrayList<Object>();
                        list.add(filedInfo.get(name));
                        list.add(objBefore);
                        list.add(objAfter);
                        map.put(name, list);
                        continue;
                    }
                    // 比较这两个值是否相等,不等则放入map
                    if (!objBefore.equals(objAfter)) {
                        List<Object> list = new ArrayList<Object>();
                        list.add(filedInfo.get(name));
                        list.add(objBefore);
                        list.add(objAfter);
                        map.put(name, list);
                    }
                }
            }
        }
        return map;
    } catch (Exception e) {
        log.error(e.getMessage());
        return null;
    }
}

}

注意,上面的方法可以优化:
一下优化后的

public class CompareEntityFiled {

    /**
     * 实体类对比
     * @param newEntity
     * @param oldEntity
     * @param filedInfo
     * @return
     */
    public static Map<String, List<Object>> compareFields(Object newEntity, Object oldEntity,Map<String,String> filedInfo) {
        try {

            Map<String, List<Object>> map = new HashMap<String, List<Object>>();

            // 只有两个对象都是同一类型的才有可比性
            if (newEntity.getClass() == oldEntity.getClass()) {
                Class clazz = newEntity.getClass();
                // 获取object的属性描述
                PropertyDescriptor[] pds = Introspector.getBeanInfo(clazz,
                        Object.class).getPropertyDescriptors();
                // 属性对比
                for (PropertyDescriptor pd : pds) {
                    // 属性名
                    String name = pd.getName();
                    // 是否当前属性选择进行比较,否跳到下一次循环
                    if (filedInfo != null && filedInfo.containsKey(name)) {
                        // get方法
                        Method readMethod = pd.getReadMethod();
                        // 在objBefore上调用get方法等同于获得objBefore的属性值
                        Object objBefore = readMethod.invoke(oldEntity);
                        // 在objAfter上调用get方法等同于获得objAfter的属性值
                        Object objAfter = readMethod.invoke(newEntity);

                        //如果是日期类型需要转化成时间戳
                        if (objBefore instanceof Timestamp) {
                            objBefore = new Date(((Timestamp) objBefore).getTime());
                        }
                        if (objAfter instanceof Timestamp) {
                            objAfter = new Date(((Timestamp) objAfter).getTime());
                        }

                        //判断开始
                        if (objBefore == null && objAfter == null) {
                            continue;
                        } else if (objBefore == null && objAfter != null) {
                            List<Object> list = new ArrayList<Object>();
                            list.add(filedInfo.get(name));
                            list.add(objBefore);
                            list.add(objAfter);
                            map.put(name, list);
                            continue;
                        }
                        // 比较这两个值是否相等,不等则放入map
                        if (!objBefore.equals(objAfter)) {
                            List<Object> list = new ArrayList<Object>();
                            list.add(filedInfo.get(name));
                            list.add(objBefore);
                            list.add(objAfter);
                            map.put(name, list);
                        }
                    }
                }
            }
            return map;
        } catch (Exception e) {
            log.error(e.getMessage());
            return null;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值