比较工具类

package com.mdgyl.common.util;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mdgyl.common.constants.BasicBusinessConstants;
import com.mdgyl.common.enums.OperateActionEnum;
import com.mdgyl.common.util.vo.ChangeInfoVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * description:
 * author: wuyc
 * createTime: 2023-12-25 09:36:15
 */
@Slf4j
public class SupplierChangeUtils {

    public static void main(String[] args) {

    }

    /**
     * 通过反射机制获取有改动的value、List值
     *
     * @param oldClazz 旧的对象
     * @param newClazz 新的对象
     * @return 改动记录列表
     */
    public static <T> List<ChangeInfoVO> getChangeList(T oldClazz, T newClazz) {
        Field[] oldFieldArr = oldClazz.getClass().getDeclaredFields();
        Field[] newFieldArr = newClazz.getClass().getDeclaredFields();

        List<ChangeInfoVO> changeList = new ArrayList<>();
        IntStream.range(0, oldFieldArr.length).forEach(index -> {
            Field oldField = oldFieldArr[index];
            String fieldName = oldField.getName();
            Object oldValue = getFieldValue(oldClazz, oldField);
            Object newValue = getFieldValue(newClazz, newFieldArr[index]);
            ChangeInfoVO changeInfoVO = ChangeInfoVO.buildChangeInfo(fieldName, oldValue, newValue);
            if (Objects.nonNull(changeInfoVO)) {
                changeList.add(changeInfoVO);
            }
        });
        return changeList;
    }

    /**
     * 通过反射机制获取有改动的value、List值
     *
     * @param oldClazz         旧的对象
     * @param newClazz         新的对象
     * @param compareFieldList 对比的列
     * @return 改动记录列表
     */
    public static <T> List<ChangeInfoVO> getChangeList(T oldClazz, T newClazz, List<String> compareFieldList) {
        if (CollectionUtils.isEmpty(compareFieldList)) {
            return getChangeList(oldClazz, newClazz);
        }

        List<ChangeInfoVO> changeList = new ArrayList<>();
        for (String field : compareFieldList) {
            try {
                // 获取旧的值
                Field oldFiled = oldClazz.getClass().getDeclaredField(field);
                oldFiled.setAccessible(true);
                Object oldValue = oldFiled.get(oldClazz);

                // 获取新的值
                Field newFiled = oldClazz.getClass().getDeclaredField(field);
                newFiled.setAccessible(true);
                Object newValue = newFiled.get(newClazz);

                ChangeInfoVO changeInfoVO = ChangeInfoVO.buildChangeInfo(field, oldValue, newValue);
                if (Objects.nonNull(changeInfoVO)) {
                    changeList.add(changeInfoVO);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return changeList;
    }

    /**
     * 通过反射机制获取有改动的value、List值
     *
     * @param oldClazzList 旧的对象
     * @param newClazzList 新的对象
     * @return 改动记录列表
     */
    public static <T> List<ChangeInfoVO> getListChangeList(List<T> oldClazzList, List<T> newClazzList) {
        // 旧数组为空、是新增
        if (CollectionUtils.isEmpty(oldClazzList)) {
            return ListUtils.mapToList(newClazzList, data -> ChangeInfoVO.buildBatchAddOrDeleteVO(null, data, OperateActionEnum.ADD.getActionType()));
        }

        // 新数组为空、是删除
        if (CollectionUtils.isEmpty(oldClazzList)) {
            return ListUtils.mapToList(newClazzList, data -> ChangeInfoVO.buildBatchAddOrDeleteVO(data, null, OperateActionEnum.DELETE.getActionType()));
        }

        // 新旧数组都不为空,可能是新增、编辑、删除
        List<ChangeInfoVO> editDeleteList = getEditOrDeleteList(oldClazzList, newClazzList);
        List<ChangeInfoVO> addList = getAddList(newClazzList);
        editDeleteList.addAll(addList);
        return editDeleteList;
    }

    /**
     * 获取新增的list
     *
     * @param newList 新数据集合
     * @return 新增的集合
     */
    private static <T> List<ChangeInfoVO> getAddList(List<T> newList) {
        return newList.stream().map(data -> {
            JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(data));
            if (jsonObject.getLong(BasicBusinessConstants.ID) != null) {
                return null;
            } else {
                return ChangeInfoVO.buildBatchAddOrDeleteVO(null, data, OperateActionEnum.ADD.getActionType());
            }
        }).filter(Objects::nonNull).collect(Collectors.toList());
    }

    /**
     * 获取集合数据编辑、新增的变更集合
     *
     * @param oldList 旧集合
     * @param newList 新集合
     * @return 改变的集合
     */
    private static <T> List<ChangeInfoVO> getEditOrDeleteList(List<T> oldList, List<T> newList) {
        return oldList.stream().map(data -> {
            JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(data));
            Long id = jsonObject.getLong(BasicBusinessConstants.ID);
            Object editObject = ListUtils.filterMapFirst(newList, editData -> getEditObject(id, editData), Objects::nonNull);
            if (Objects.nonNull(editObject)) {
                return ChangeInfoVO.buildBatchEditVO(id, OperateActionEnum.EDIT.getActionType(), getChangeList(data, editObject));
            } else {
                return ChangeInfoVO.buildBatchAddOrDeleteVO(data, null, OperateActionEnum.DELETE.getActionType());
            }
        }).collect(Collectors.toList());
    }

    /**
     * 获取编辑的object
     *
     * @param id           行id
     * @param changeObject 有改动的object
     * @return 编辑的object
     */
    private static Object getEditObject(Long id, Object changeObject) {
        JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(changeObject));
        if (jsonObject.getLong(BasicBusinessConstants.ID) != null && id.equals(jsonObject.getLong(BasicBusinessConstants.ID))) {
            return changeObject;
        }
        return null;
    }

    /**
     * 获取field列的属性值
     *
     * @param clazz 获取对象
     * @param field 获取的列
     * @return value
     */
    private static <T> Object getFieldValue(T clazz, Field field) {
        field.setAccessible(true);
        try {
            return field.get(clazz);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

}

代码主要实现了通过反射机制比较两个对象(或两个对象列表)之间的差异,并生成一个包含变更信息的列表。下面是对每个方法和相关逻辑的详细分析:

  1. getChangeList(T oldClazz, T newClazz)

    • 功能:比较两个对象的所有字段,生成字段变更信息的列表。
    • 实现:通过反射获取旧对象和新对象的字段,比较它们的值,并生成 ChangeInfoVO 对象。如果字段值有变动,则将变更信息添加到结果列表中。
    • 问题:在获取新值时直接使用 newFieldArr[index],这可能导致字段顺序不一致的问题。最好使用字段名称来获取值,以避免顺序问题。
  2. getChangeList(T oldClazz, T newClazz, List<String> compareFieldList)

    • 功能:比较指定字段的变化,生成字段变更信息的列表。
    • 实现:根据提供的字段列表获取旧对象和新对象的指定字段的值,并比较它们。如果字段值有变动,则将变更信息添加到结果列表中。
    • 问题:如果字段不存在或反射获取值出错,方法会捕获并打印异常,但不会处理这些异常。可以考虑将异常处理逻辑改为更健壮的方式。
  3. getListChangeList(List<T> oldClazzList, List<T> newClazzList)

    • 功能:比较两个对象列表,生成变更信息的列表,包括新增、编辑和删除。
    • 实现:分别处理新增和删除,调用 getEditOrDeleteList 方法处理编辑和删除,并合并结果。
    • 问题:在旧列表为空的情况下,方法使用 ListUtils.mapToList 生成新增信息,但具体实现取决于 ListUtils 的实现,可能需要检查其正确性。
  4. getAddList(List<T> newList)

    • 功能:获取新增的对象。
    • 实现:将每个对象转换为 JSON 格式,然后根据 ID 判断是否为新增对象。如果 ID 为 null,则认为对象是新增的。
    • 问题:如果 ID 不存在可能需要更详细的判断逻辑,确保新增判断的准确性。
  5. getEditOrDeleteList(List<T> oldList, List<T> newList)

    • 功能:获取编辑或删除的对象。
    • 实现:检查旧列表中的每个对象是否在新列表中存在,如果存在则检查是否有编辑;如果不存在则标记为删除。
    • 问题:这个方法的实现依赖于 ListUtils.filterMapFirst,需要确保它能正确处理数据过滤和映射。
  6. getEditObject(Long id, Object changeObject)

    • 功能:根据 ID 获取编辑的对象。
    • 实现:将对象转换为 JSON 格式,然后根据 ID 判断对象是否需要编辑。
    • 问题:确保 ID 的比较准确且 JSON 转换不会丢失重要信息。
  7. getFieldValue(T clazz, Field field)

    • 功能:通过反射获取字段的值。
    • 实现:设置字段可访问,然后获取字段值。如果出错则捕获异常并返回 null
    • 问题:异常处理可能需要更细致的错误日志记录或处理。

整体来看,代码实现了基本的对象比较和变更记录功能。为了增强代码的健壮性和可维护性,可以考虑对异常处理、字段获取逻辑、以及依赖于其他工具类的方法进行详细检查和改进。

package com.mdgyl.common.util.vo;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mdgyl.common.constants.BasicBusinessConstants;
import com.mdgyl.common.enums.OperateActionEnum;
import lombok.Data;

import java.util.List;
import java.util.Objects;

/**
 * description:
 * author: wuyc
 * createTime: 2023-12-25 09:38:16
 */
@Data
public class ChangeInfoVO {

    /**
     * 改变的字段
     */
    private String field;

    /**
     * 操作类型 新增、编辑、删除
     */
    private String operateType;


    /**
     * 唯一id
     */
    private String uniqueId;

    /**
     * 子数据
     */
    private List<ChangeInfoVO> childList;

    /**
     * 改变之前的值
     */
    private Object oldValue;

    /**
     * 改变之后的值
     */
    private Object newValue;


    /**
     * 构建改变的值
     *
     * @param fieldName 列表
     * @param oldValue  旧值
     * @param newValue  新值
     * @return ChangeInfoVO
     */
    public static ChangeInfoVO buildChangeInfo(String fieldName, Object oldValue, Object newValue) {
        // 新旧值都为空,说明无改变
        if ((Objects.isNull(oldValue) && Objects.isNull(newValue))) {
            return null;
        }

        ChangeInfoVO changeInfoVO = new ChangeInfoVO();
        changeInfoVO.setField(fieldName);
        changeInfoVO.setOldValue(oldValue);
        changeInfoVO.setNewValue(newValue);
        if (Objects.isNull(oldValue)) {
            changeInfoVO.setOperateType(OperateActionEnum.ADD.getActionType());
        } else if (Objects.isNull(newValue)) {
            changeInfoVO.setOperateType(OperateActionEnum.DELETE.getActionType());
        } else if (!oldValue.equals(newValue)) {
            changeInfoVO.setOperateType(OperateActionEnum.EDIT.getActionType());
        } else {
            return null;
        }
        return changeInfoVO;
    }

    /**
     * @param uniqueId    唯一id
     * @param operateType 操作类型
     * @param childList   有改动记录列表的子列表
     * @return ChangeInfoVO
     */
    public static ChangeInfoVO buildBatchEditVO(Long uniqueId, String operateType, List<ChangeInfoVO> childList) {
        ChangeInfoVO changeInfoVO = new ChangeInfoVO();
        changeInfoVO.setOperateType(operateType);
        changeInfoVO.setUniqueId(uniqueId.toString());
        changeInfoVO.setChildList(childList);
        return changeInfoVO;
    }

    /**
     * 批量删除、新增构建改变记录
     *
     * @param oldObject   旧object
     * @param newObject   新object
     * @param operateType 操作类型
     * @return ChangeInfoVO
     */
    public static ChangeInfoVO buildBatchAddOrDeleteVO(Object oldObject, Object newObject, String operateType) {
        ChangeInfoVO changeInfoVO = new ChangeInfoVO();
        changeInfoVO.setOperateType(operateType);
        // 如果是删除的时候,需要设置旧的行id
        if (Objects.nonNull(oldObject)) {
            String oldJsonStr = JSON.toJSONString(oldObject);
            changeInfoVO.setOldValue(oldJsonStr);
            JSONObject jsonObject = JSON.parseObject(oldJsonStr);
            changeInfoVO.setUniqueId(jsonObject.getString(BasicBusinessConstants.ID));
        }

        changeInfoVO.setNewValue(Objects.isNull(newObject) ? null : JSON.toJSONString(newObject));
        return changeInfoVO;
    }

}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值