首页 > 编程语言 >记录Java对象修改前和修改后的变化

记录Java对象修改前和修改后的变化

时间:2023-11-25 10:23:48浏览次数:48  
标签:return 记录 oldBean Object value 修改 Java import

一、记录跟变信息对象

/**
 * @author FengQing
 * @program yf-client
 * @description
 * @date 2023/11/01
 */
@Getter
@Setter
@ToString
public class ChangePropertyMsg {
    /**
     * 变更信息
     */
    private String changeMsg;
    /**
     * 变更属性集合
     */
    private List<String> properties;
}

 

二、工具类(传入两个相同类型的对象,对比属性得到修改信息)

提示:监听属性变化是通过【ApiModelProperty】注解,当然你也可以通过自定义注解实现;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ArrayUtil;
import com.yf.client.entity.log.ChangePropertyMsg;
import com.yf.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import io.swagger.annotations.ApiModelProperty;
import org.apache.commons.lang.ObjectUtils;
import java.lang.reflect.Field;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * @author FengQing
 * @program yf-client
 * @description
 * @date 2023/11/01
 */
@Slf4j
public class BeanChangeUtil<T> {

    /**
     * 传入两个相同类型的对象,对比属性得到修改信息
     * @param oldBean
     * @param newBean
     * @return 属性修改信息
     */
    public static <aClass> String getChangeInfo(Object oldBean, Object newBean){
        Class aClass = oldBean.getClass();
        BeanChangeUtil<aClass> t = new BeanChangeUtil<>();
        ChangePropertyMsg cfs = t.contrastObj(oldBean, newBean);
        if (StringUtils.isNotEmpty(cfs.getChangeMsg())) {
            return cfs.getChangeMsg();
        }
        return null;
    }
    /**
     * 传入两个相同类型的对象,对比属性得到修改信息
     * @param oldBean
     * @param newBean
     * @return **完整属性修改信息**
     */
    public ChangePropertyMsg contrastObj(Object oldBean, Object newBean) {
        // 转换为传入的泛型T
        T oldPojo = (T) oldBean;
        // 通过反射获取类型及字段属性
        Field[] fields = oldPojo.getClass().getDeclaredFields();
        return jdk8OrAfter(Arrays.asList(fields), oldPojo, (T) newBean);
    }

    // lambda表达式,表达式内部的变量都是final修饰,需要传入final类型的数组
    private ChangePropertyMsg jdk8OrAfter(List<Field> fields, T oldBean, T newBean) {
        ChangePropertyMsg cf = new ChangePropertyMsg();
        // 创建字符串拼接对象
        StringBuilder str = new StringBuilder();
        List<String> fieldList = new ArrayList<>();
        fields.forEach(field -> {
            field.setAccessible(true);
            if (field.isAnnotationPresent(ApiModelProperty.class)) {
                try {
                    // 获取属性值
                    Object newValue = field.get(newBean);
                    Object oldValue = field.get(oldBean);
                    if (StringUtils.isNotNull(newValue)) {
                        if (ObjectUtils.notEqual(oldValue, newValue)) {
                            boolean isOldValueArray = ArrayUtil.isArray(oldValue);
                            boolean isNewValueArray = ArrayUtil.isArray(newValue);

                            if (isOldValueArray && isNewValueArray) {
                                Object[] oldArray = (Object[]) oldValue;
                                Object[] newArray = (Object[]) newValue;
                                if (!Arrays.deepEquals(oldArray, newArray)) {
                                    fieldList.add(field.getName());
                                    str.append(field.getAnnotation(ApiModelProperty.class).value() + ":");
                                    str.append("修改前=【" + Arrays.toString(oldArray) + "】,修改后=【" + Arrays.toString(newArray) + "】;\n");
                                }
                            } else {
                                fieldList.add(field.getName());
                                str.append(field.getAnnotation(ApiModelProperty.class).value() + ":");
                                str.append("修改前=【" + formatPropertyValue(oldValue) + "】,修改后=【" + formatPropertyValue(newValue) + "】;\n");
                            }
                        }
                    }
                } catch (Exception e) {
                    log.error("比对Bean属性是否变化失败,", e);
                }
            }
        });
        cf.setChangeMsg(str.toString());
        cf.setProperties(fieldList);
        return cf;
    }

    /**
     * 时间处理
     * @param value
     * @return
     */
    private static Object formatPropertyValue(Object value) {
        if (value instanceof Date) {
            return DateUtil.format((Date) value, "yyyy-MM-dd");
        } else if (value instanceof LocalDateTime) {
            LocalDateTime localDateTimeValue = (LocalDateTime) value;
            return localDateTimeValue.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        }
        return value;
    }
}

 

三、在修改业务中使用步骤(我这边使用的mybatis-plus,其它的同理方式处理)

 /**
     * 更新操作(业务层)
     * @param channel
     * @return
     */
    @Override
    @Transactional(rollbackFor = {Exception.class, RuntimeException.class, MybatisPlusException.class})
    public void updateChannel(ChannelParam channel) {
        // 1、查询修改前的数据
        ChannelVo channelVo = this.selectChannelById(channel.getId());
     // 2、修改前的对象跟前端返回的对象不一样如:前端传来的“ChannelParam”,修改前是“ChannelVo”对象,把它复制到统一对象中 ChannelParam oldParam = new ChannelParam(); BeanUtil.copyProperties(channelVo, oldParam); Channel data = new Channel;
     BeanUtil.copyProperties(channel, data); super.updateById(data); // 记录日志对象 ChannelLogParam logParam = new ChannelLogParam();

     // 调用监听属性变化工具类 BeanChangeUtil<ChannelParam> t = new BeanChangeUtil<>(); ChangePropertyMsg cfs = t.contrastObj(oldParam, channel); if (StringUtils.isNotBlank(cfs.getChangeMsg())) {
        logParam.setUpdateObj(cfs.getProperties().toString()); logParam.setUpdateMsg(cfs.getChangeMsg()); }      // 添加日志记录 channelLogService.insertChannelLogging(logParam); }

 

四、数据库存储效果如下图:

 

到这里就大功告成了。

 

标签:return,记录,oldBean,Object,value,修改,Java,import
From: https://www.cnblogs.com/springclout/p/17855236.html

相关文章

  • Java Web 实现文件上传和下载接口功能
    1.上传java代码实现@ResponseBody@PostMapping("/upload")publicResponseVoupload(@RequestParam(value="file",required=false)MultipartFilemultipartFile){Filefile=newFile("上传到服务器的文件地址");try{......
  • 【开源】基于JavaWeb的快乐贩卖馆管理系统 毕业设计
    一、摘要1.1项目介绍基于JAVA+Vue+SpringBoot+MySQL的快乐贩卖馆管理系统,包含了视频模块、视频收藏模块、视频打分模块、视频交友模块、视频购物车模块和视频订单模块,还包含系统自带的用户管理、部门管理、角色管理、菜单管理、日志管理、数据字典管理、文件管理、图表展示等基础......
  • Java零基础入门-数组
    Java零基础入门-数组前言Java是一门面向对象的编程语言,被广泛应用于各个领域。数组是Java编程中最基本也是最重要的数据结构之一,它可以用来存储一组数据,并且方便进行操作和处理。本文将为大家介绍Java数组的基本概念、语法和常见应用场景,帮助初学者快速入门。摘要本文将从以下......
  • 【开源】基于JavaWeb的智慧家政系统 毕业设计
    一、摘要1.1项目介绍基于微信小程序+JAVA+Vue+SpringBoot+MySQL的智慧家政系统,包含了地址管理模、订单管理、家政分类管理、家政服务管理、用户反馈管理模块,还包含系统自带的用户管理、部门管理、角色管理、菜单管理、日志管理、数据字典管理、文件管理、图表展示等基础模块,基于微......
  • Java二级医院区域HIS信息管理系统源码(SaaS服务)
    一个好的HIS系统,要具有开放性,便于扩展升级,增加新的功能模块,支撑好医院的业务的拓展,而且可以反过来给医院赋能,最终向更多的患者提供更好的服务。系统采用前后端分离架构,前端由Angular、JavaScript开发;后端使用Java语言开发。融合B/S版电子病历系统,支持电子病历四级。系统运行稳定、......
  • Java报表详情介绍及示例程
    Java报表详情介绍及示例程序简介Java报表是一种用于展示数据并提供可视化分析的工具。它可以将数据转化为图表、表格、图像等形式,帮助用户更直观地理解数据的含义和趋势。Java报表通常用于企业管理、数据分析、业务决策等领域,具有易于使用、灵活性高、功能强大等特点。常用的Java报......
  • java Calendar、LocalDateTime、LocalDate日期加减
    Calendar日期获取,设置,加减创建一个日历对象获取当前年份,月份,日期等.....设置指定年份,月份,日期等.....Calendarcalendar=Calendar.getInstance();//创建一个日历对象intyear=calendar.get(calendar.YEAR);//获取当前年份System.out.p......
  • 在.Net中使用Java代码?
    前言你没有看错,我确实在.Net6的项目中在编写java,我都usingjava了,算不算在写java那?usingcom.microsoft.sqlserver.jdbc;usingjava.sql;并且编辑器还带提示的功能这一切都是借助IKVM来实现的,或许有些人还听说过使用IKVM的CLI命令来转换jar包,比如使用Bing搜索:ikvm转换jar包......
  • 5-Windows系统上安装java
      有一些生信软件是java语言写的,就需要安装java才能运行,下面展示java的安装。 1,下载(https://www.oracle.com/java/technologies/downloads/#java17) 官网下载java2,双击安装,这里的安装位置最好按照默认的来,不更改,在C盘。 安装3,配置环境变量,为了让任何目录......
  • AJAX记录
    AJAX目录AJAX1.绑定事件点击判断类名的2.事件文件列表3.关联标签4.转义符号5.耦合性6.事件循环经典面试题1.绑定事件点击判断类名的document.querySelector('.list').addEventListener('click',(e)=>{if(e.target.classList.contains('edit')){editModal.sh......