java常用BeanCompareUtil 注解 + 反射实现 (实例说明)

27 篇文章 0 订阅
15 篇文章 0 订阅

背景

在开发过程中经常会使用到一种场景就是比较内存中的两个bean 数据有什么同。其实这种功能算是一个非常常用的场景。

使用实例说明

一共需要以下的几个模块

  1. FieldComparison 自定义注解,主要是标识需要比较的bean 中的字段。
  2. BeanCompareUtil 核心util 主要是实现compare 方法。
  3. FieldMapping 字段映射关系,选用可以对特定的字段进行转义。
  4. DefaultFieldMapping fieldMapping的实现类。可以扩展。

public class BeanCompareUtil {
    public static List<BeanCompareResult> compare(Object oldBean, Object newBean)
            throws InvocationTargetException, IllegalAccessException,
            IntrospectionException, NullPointerException, InstantiationException, NoSuchMethodException {
        if (oldBean == null || newBean == null) {
            throw new IllegalArgumentException("the argument must be not null");
        }
        if (oldBean.getClass() != newBean.getClass()) {
            return Collections.emptyList();
        }
        List<BeanCompareResult> list = new ArrayList<>();
        Class<?> aClass = oldBean.getClass();
        while (aClass != null) {
            Field[] fieldList = aClass.getDeclaredFields();
            for (Field field : fieldList) {
                if (field.isAnnotationPresent(FieldComparison.class)) {
                    BeanCompareResult comResult = new BeanCompareResult();
                    PropertyDescriptor pd = new PropertyDescriptor(field.getName(), aClass);
                    String name = pd.getName();
                    comResult.setCode(name);
                    Method getMethod = pd.getReadMethod();
                    Object o1 = getMethod.invoke(oldBean);
                    Object o2 = getMethod.invoke(newBean);
                    if (o2 == null) {
                        continue;
                    }
                    String first = null == o1 ? "" : String.valueOf(o1).trim();
                    String second = String.valueOf(o2).trim();
                    if (field.isAnnotationPresent(FieldComparison.class)) {
                        FieldComparison fieldComparison = field.getAnnotation(FieldComparison.class);
                        String value = fieldComparison.codeName();
                        Class<? extends FieldMapping> mapping = fieldComparison.mapping();
                        Method method = mapping.getMethod("mapping", Map.class);
                        Object invoke = method.invoke(mapping.newInstance(), new HashMap<>());
                        if (invoke != null) {
                            Map<String, String> map = (Map<String, String>) invoke;
                            String s = map.get(first);
                            String s2 = map.get(second);
                            comResult.setOldValue(s);
                            comResult.setNewValue(s2);
                        } else {
                            comResult.setOldValue(first);
                            comResult.setNewValue(second);
                        }
                        comResult.setName(value);
                    }
                    if (!first.equals(second)) {
                        list.add(comResult);
                    }
                }
            }
            aClass = aClass.getSuperclass();
        }
        return list;
    }
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface FieldComparison {

    /**
     * 字段对应的中文名从
     *
     * @return
     */
    String codeName() default "";

    /**
     * 字段对应关系,如 1->下线 0->上线
     * @return
     */
    Class<? extends FieldMapping> mapping() default DefaultFieldMapping.class;
}
public interface FieldMapping {
    Map<String, String> mapping(Map<String,String> map);
}
public class DefaultFieldMapping implements FieldMapping {
    @Override
    public Map<String, String> mapping(Map<String, String> map) {
        return null;
    }
}

使用方式

  1. 在需要compare 的地方加上注释
    在这里插入图片描述
  2. 定义结果接受的bean

public class BeanCompareResult {
    private String code;
    private String name;
    private String oldValue;
    private String newValue;

    private String extendRemark;

    public String getExtendRemark() {
        return extendRemark;
    }

    public void setExtendRemark(String extendRemark) {
        this.extendRemark = extendRemark;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getOldValue() {
        return oldValue;
    }

    public void setOldValue(String oldValue) {
        this.oldValue = oldValue;
    }

    public String getNewValue() {
        return newValue;
    }

    public void setNewValue(String newValue) {
        this.newValue = newValue;
    }

    @Override
    public String toString() {
        return "BeanCompareResult{" +
                "code='" + code + '\'' +
                ", name='" + name + '\'' +
                ", oldValue='" + oldValue + '\'' +
                ", newValue='" + newValue + '\'' +
                ", extendRemark='" + extendRemark + '\'' +
                '}';
    }
}
  1. 传入oldbean 和 newbean进行比较和接收结果。
    在这里插入图片描述

执行效果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值