Java实体文本对比工具

相关注解

  1. 忽略字段注解:该注解下的实体字段不参与文本对比
	@Target({ElementType.FIELD})
	@Retention(RetentionPolicy.RUNTIME)
	public @interface IgnorField {
	}
  1. Swagger-ApiModelProperty注解: 通过该注解获取字段中文说明

返回实体

	@Data
	@ApiModel("实体属性对比类")
	public class CompareFiledInfo {
	
	    @ApiModelProperty("字段名称-对应字段名")
	    private String filedName;
	
	    @ApiModelProperty("字段说明-对应ApiModelProperty注解value值")
	    private String filedExplain;
	
	    @ApiModelProperty("原值")
	    private Object oldValue;
	
	    @ApiModelProperty("当前值")
	    private Object newValue;
	}
	@Data
	@ApiModel("对象比较结果")
	public class CompareObjInfo<T> {
	    @ApiModelProperty("操作类型 0-新增 1-修改 2-删除")
	    private int operateType;
	
	    @ApiModelProperty("旧对象")
	    private T oldObj;
	
	    @ApiModelProperty("新对象")
	    private T newObj;
	}

文本登录工具类:

	@Slf4j
	public class PropertyUtils {
	    private PropertyUtils() {
	    }
	
	    /**
	     * 忽略大小写转换bean类型
	     *
	     * @param obj 转换的源对象
	     * @param clz 目标对象
	     * @return 转换后的对象
	     */
	    public static <T> T transferObjectIgnoreCase(Object obj, Class<T> clz) {
	        T result = null;
	        try {
	            if (obj != null && !obj.equals("")) {
	                result = clz.newInstance();
	                //获取目标类的属性集合
	                Map<String, Field> destPropertyMap = new HashMap<>();
	                for (Field curField : clz.getDeclaredFields()) {
	                    //排除不需要对比的字段
	                    if (curField.isAnnotationPresent(IgnorField.class)) {
	                        continue;
	                    }
	                    destPropertyMap.put(curField.getName().toLowerCase(), curField);
	                }
	                //拷贝属性
	                for (Field curField : obj.getClass().getDeclaredFields()) {
	                    Field targetField = destPropertyMap.get(curField.getName().toLowerCase());
	                    if (targetField != null) {
	                        targetField.setAccessible(true);
	                        curField.setAccessible(true);
	                        targetField.set(result, curField.get(obj));
	                    }
	                }
	            }
	        } catch (Exception e) {
	            log.error("忽略大小写转换bean类型失败", e);
	            return null;
	        }
	        return result;
	    }
	
	    /**
	     * 集合对比
	     *
	     * @param oldList 老集合
	     * @param newList 新集合
	     * @param filed   对比标识字段名
	     * @param <T>     泛型实体
	     * @return 对比结果
	     */
	    public static <T> List<CompareObjInfo<T>> compareList(List<T> oldList, List<T> newList, String filed) {
	        boolean oldEmpty = CollUtil.isEmpty(oldList);
	        boolean newEmpty = CollUtil.isEmpty(newList);
	        if (oldEmpty || newEmpty) {
	            Asserts.fail(LocalLangUtil.get("property.utils.collectCompareEmptyErrorInfo"));
	        }
	        List<CompareObjInfo<T>> compareObjInfos = null;
	        if (oldEmpty && newEmpty) {
	            return compareObjInfos;
	        }
	        if (!oldEmpty && !newEmpty && (oldList.get(0).getClass() != newList.get(0).getClass())) {
	            Asserts.fail(LocalLangUtil.get("property.utils.collectCompareTypeErrorInfo"));
	        }
	        try {
	            Field field = oldList.get(0).getClass().getDeclaredField(filed);
	            //设置对象的访问权限,保证对private的属性的访问
	            field.setAccessible(true);
	            Map<Object, T> tempMap = new HashMap<>();
	            for (T value : oldList) {
	                // 将实体信息(key-对比标识字段值;value-实体信息)放置集合存储
	                tempMap.put(field.get(value), value);
	            }
	            //step 1 循环遍历新数据,如果id为null则为新增,id在老数据中存在则比较,老数据中不存在则为删除
	            compareObjInfos = new ArrayList<>();
	            CompareObjInfo<T> compareObjInfo;
	            for (T obj : newList) {
	                compareObjInfo = new CompareObjInfo<>();
	                // 获取新的对比识别字段的值
	                Object newValueId = field.get(obj);
	
	                //newValue为nll则为新增
	                if (null == newValueId || !tempMap.containsKey(newValueId)) {
	                    compareObjInfo.setOperateType(0);
	                    compareObjInfo.setNewObj(obj);
	                    compareObjInfos.add(compareObjInfo);
	                    continue;
	                }
	                if (tempMap.containsKey(newValueId)) {
	                    List<CompareFiledInfo> compareFiledInfos = compareObjFields(tempMap.get(newValueId), obj);
	                    if (!compareFiledInfos.isEmpty()) {
	                        compareObjInfo.setOperateType(1);
	                        compareObjInfo.setOldObj(tempMap.get(newValueId));
	                        compareObjInfo.setNewObj(obj);
	                        compareObjInfos.add(compareObjInfo);
	                    }
	                    tempMap.remove(newValueId);
	                }
	            }
	            //tempList最后的为被删除的
	            if (!tempMap.isEmpty()) {
	                for (T obj : tempMap.values()) {
	                    compareObjInfo = new CompareObjInfo<>();
	                    compareObjInfo.setOperateType(2);
	                    compareObjInfo.setOldObj(obj);
	                    compareObjInfo.setNewObj(null);
	                    compareObjInfos.add(compareObjInfo);
	                }
	            }
	
	        } catch (Exception e) {
	            log.error("集合对比失败", e);
	            Asserts.fail(LocalLangUtil.get("property.utils.collectCompareFailedErrorInfo"));
	        }
	
	        return compareObjInfos;
	    }
	
	    public static <T> List<CompareFiledInfo> compareObjFields(T oldObj, T newObj) {
	        List<CompareFiledInfo> changeFileds = new ArrayList<>();
	        try {
	            Class<?> clazz = oldObj.getClass();
	            PropertyDescriptor[] pds = Introspector.getBeanInfo(clazz, Object.class).getPropertyDescriptors();
	            CompareFiledInfo compareFiledInfo = null;
	            for (PropertyDescriptor pd : pds) {
	                compareFiledInfo = new CompareFiledInfo();
	                String name = pd.getName();
	                //获取属性ApiModelProperty注解值
	                Field filed = oldObj.getClass().getDeclaredField(name);
	                //排除字段
	                if (filed.isAnnotationPresent(IgnorField.class)) {
	                    continue;
	                }
	                compareFiledInfo.setFiledName(name);
	                if (filed.isAnnotationPresent(ApiModelProperty.class)) {
	                    compareFiledInfo.setFiledExplain(filed.getAnnotation(ApiModelProperty.class).value());
	                }
	
	                Method readMethod = pd.getReadMethod();
	                // 调用get方法等同于获得object的属性值
	                Object oldValue = readMethod.invoke(oldObj);
	                Object newValue = readMethod.invoke(newObj);
	
	                boolean whetherChange = (ObjectUtil.isEmpty(oldValue) && ObjectUtil.isNotEmpty(newValue)) || (ObjectUtil.isNotEmpty(oldValue) && ObjectUtil.isEmpty(newValue));
	
	                if (ObjectUtil.isNotEmpty(oldValue) && ObjectUtil.isNotEmpty(newValue)) {
	                    if (pd.getPropertyType() != BigDecimal.class) {
	                        whetherChange = !oldValue.equals(newValue);
	                    } else {
	                        BigDecimal oldDecimal = (BigDecimal) oldValue;
	                        BigDecimal newDecimal = (BigDecimal) newValue;
	                        whetherChange = oldDecimal.compareTo(newDecimal) != 0;
	                    }
	                }
	
	                if (whetherChange) {
	                    compareFiledInfo.setOldValue(oldValue);
	                    compareFiledInfo.setNewValue(newValue);
	                    changeFileds.add(compareFiledInfo);
	                }
	            }
	        } catch (Exception e) {
	            log.error("字段对比失败", e);
	            Asserts.fail(LocalLangUtil.get("property.utils.filedtCompareFailedErrorInfo"));
	        }
	        return changeFileds;
	    }
	}

使用说明

	public class CapitalMargin  {
	
	    @ApiModelProperty(value = "主键")
	    @IgnorField
	    private Long id;
	
	    @ApiModelProperty(value = "所属时间")
	    @IgnorField
	    private LocalDateTime belongDate;
	
	    @ApiModelProperty(value = "所属修改时间")
	    @IgnorField
	    private LocalDateTime belongChangeDate;
	
	    @ApiModelProperty(value = "产品类型数据字典id")
	    private Long productTypeId;
	
	}
	 		List<CompareObjInfo<CapitalMargin>> compareObjInfos = PropertyUtils.compareList(list, allInfos, "no");
	            if (!CollUtil.isEmpty(compareObjInfos)) {
	                insertList = new ArrayList<>();
	                updateList = new ArrayList<>();
	                deleteList = new ArrayList<>();
	                for (CompareObjInfo<CapitalMargin> compareObjInfo : compareObjInfos) {
	                    int operateType = compareObjInfo.getOperateType();
	                    switch (operateType) {
	                        case 0:
	                            // 新增
	                            insertList.add(compareObjInfo.getNewObj());
	                            break;
	                        case 1:
	                            // 修改
	                            Long id = compareObjInfo.getOldObj().getId();
	                            updateList.add(id);
	                            CapitalMargin newObj = compareObjInfo.getNewObj();
	                            newObj.setBelongChangeId(id);
	                            newObj.setStatusChangeReson("0");
	                            insertList.add(newObj);
	                            break;
	                        case 2:
	                            // 删除
	                            deleteList.add(compareObjInfo.getOldObj().getId());
	                            break;
	                        default:
	                            break;
	                    }
	                }
	}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值