java手写操作日志功能:切面分析和写切面前的一些需要方法(三)

一.1.先做一个前置通知和后置通知,嗯。。。出现异常也要处理
2.要写个数据对比的方法,得出有修改的字段还有他们的新值和旧值
3.数据对比里需要调用对应mapper查数据库得到旧值,才能对比

二.边撸代码边说呗 ,不过代码顺序得和上面的逻辑思路顺序倒着来
1.写个mapper调用方法,返回旧数据实体,首先要拿到id或者ids

 /**
     * ****获取对象里某个字段的值**(这里是获取id或ids)**
     *
     * @param object
     * @param fieldName
     * @return
     * @throws Exception
     */
    public static List<String> getFieldValue(Object object, String fieldName) throws Exception {
        **//定义返回值**
        List<String> result = new ArrayList<>();
        Field field = object.getClass().getDeclaredField(fieldName);
        field.setAccessible(true);
        Object value = field.get(object);
        Class fieldType = field.getType();
        **//判断java字段类型(为了兼容批量操作不传集合,传逗号分割的字符串的)**
        if (Collection.class.isInstance(fieldType)) {
            result = (ArrayList<String>) value;
        } else {
            String[] valueStr = value.toString().split(",");
            result = Arrays.asList(valueStr);
        }
        return result;
    }
/**
     * 取得旧数据对象
     *
     * @param fieldValue       字段值,这里是id值
     * @param operationLogFlag 日志注解
     * @return
     * @throws IllegalAccessException
     * @throws InstantiationException
     */
  public static Object getResult(String fieldValue, OperationLogFlag operationLogFlag) throws IllegalAccessException, InstantiationException {
        **//加个断言,免得真出现没id也进到这逻辑的情况**
        Assert.notNull(fieldValue, "未解析到id值,请检查前台传递参数是否正确");
        **//从注解里拿到要查询数据库所调用的class文件**
        Class serviceclass = operationLogFlag.serviceclass();
        **//想用newInstance()但是好像由于是接口没有构造函数,所以直接从ioc容器里拿直接点**
        BaseMapper baseMapper = (BaseMapper) SpringContextUtil.getBean(serviceclass);
        return baseMapper.selectById(fieldValue);
    }

想想还得附上SpringContextUtil代码。。。以下就是

/**
 * Spring上下文获取工具类
 */
@Component
public class SpringContextUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    /**
     * 设置上下文
     *
     * @param applicationContext
     * @throws BeansException
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringContextUtil.applicationContext = applicationContext;
    }

    /**
     * 获取上下文
     *
     * @return
     */
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    /**
     * 通过名字获取上下文中的bean
     *
     * @param name
     * @return
     */
    public static Object getBean(String name) {
        return applicationContext.getBean(name);
    }

    /**
     * 通过类型获取上下文中的bean
     *
     * @param requiredType
     * @return
     */
    public static Object getBean(Class<?> requiredType) {
        return applicationContext.getBean(requiredType);
    }

}

2.得出旧对象,开始比较了,下面是比较的代码

/**
     * 获取两个对象同名属性内容不相同的列表
     *
     * @param newObject 新对象
     * @param oldObject 旧对象
     * @return
     * @throws IllegalAccessException
     */
    public static List<Map<String, Object>> getTwoObjectDiff(Object newObject, Object oldObject) throws IllegalAccessException {
      List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        **//取得两个对象的class**
        Class<?> newObjectClass = newObject.getClass();
        Class<?> oldObjectClass = oldObject.getClass();
        **//取得对象的各个属性,要一个一个比较字段**
        Field[] newObjectClassDeclaredFields = newObjectClass.getDeclaredFields();
        Field[] oldObjectClassDeclaredFields = oldObjectClass.getDeclaredFields();
        **//开始遍历newObjectClass属性列表**
        for (int i = 0; i < newObjectClassDeclaredFields.length; i++) {
            **//循环内部开始遍历oldObjectClass属性列表**
            for (int j = 0; j < oldObjectClassDeclaredFields.length; j++) {
                //如果newObjectClass[i]属性名与oldObjectClass[i]属性名内容相同,就开始比较value
                Object newName = newObjectClassDeclaredFields[i].getName();
                Object oldName = oldObjectClassDeclaredFields[j].getName();
                if (newName.equals(oldName)) {
                    **//把新旧数据的字段设为可使用**
                    newObjectClassDeclaredFields[i].setAccessible(true);
                    oldObjectClassDeclaredFields[j].setAccessible(true);
                    **//把新旧自字段值做个处理,避免出现类似旧值为null而传进来的是"",这样比就很尴尬,这种情况其实是没更新的,只是前后端传值不统一造成的**
                    Object newValue = newObjectClassDeclaredFields[i].get(newObject);
                    Object oldValue = oldObjectClassDeclaredFields[j].get(oldObject);
                    newValue = disposeValue(newValue);
                    oldValue = disposeValue(oldValue);
                    **//如果newObjectClassDeclaredFields[i]属性值与oldObjectClassDeclaredFields[j]属性值内容不相同**
                    if (!compareTwoObject(newValue, oldValue)) {
                        Map<String, Object> changeMap = new HashMap<String, Object>();
                        ApiModelProperty apiModelProperty = newObjectClassDeclaredFields[i].getAnnotation(ApiModelProperty.class);
                        String fieldName = "";
                        if (apiModelProperty != null) {
                            fieldName = apiModelProperty.value();
                        } else {
                            fieldName = newObjectClassDeclaredFields[i].getName();
                        }
                        changeMap.put("字段名", fieldName);
                        changeMap.put("新值", newValue);
                        changeMap.put("旧值", oldValue);
                        list.add(changeMap);
                    }
                    break;
                }
            }
        }
        return list;
    }
     /**
     * 对比两个数据值是否相同
     *
     * @param object1,object2
     * @return boolean类型
     */
    public static boolean compareTwoObject(Object object1, Object object2) {
    
        if (object1 == null && object2 == null) {
            return true;
        }
        if (object1 == null && object2 != null) {
            return false;
        }
        if (object1.equals(object2)) {
            return true;
        }
        return false;
    }

    /**
     * string集合转字符串
     *
     * @param list(string)
     * @return
     */
    public static String listToStr(List<String> list) {
        final String SEPARATOR = ",";
        String result = "";
        StringBuilder stringBuilder = new StringBuilder();
        if (CollectionUtils.isNotEmpty(list)) {
            for (String string : list) {
                stringBuilder.append(string);
                stringBuilder.append(SEPARATOR);
            }
        }
        result = stringBuilder.toString();
        result = result.substring(0, result.length() - 1);
        return result;
    }

    /**
     * 日期转字符串
     *
     * @param date
     * @param pattern
     * @return
     */
    public static String formatDate(Date date, String pattern) {
        String format = pattern;
        if (date == null) {
            return "";
        }
        if (pattern == null) {
            format = "yyyy-MM-dd";
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(date);
    }

 /**
     * 处理下字段值,不然会影响判断和存储
     *
     * @param value 字段值
     * @return
     */
    public static Object disposeValue(Object value) {
        **//新旧前后全部赋值为"",当做没改变**
        if (Objects.isNull(value)) {
            value = "";
        }
        **//日期类型还得处理下,免得出现时间戳**
        if (StringUtils.isNotEmpty(value.toString())) {
            if (value instanceof Date || value instanceof java.sql.Date) {
                value = CommonUtil.formatDate((Date) value, "yyyy-MM-dd");
            }
        }
        return value;
    }

你可能感兴趣的:(Java开发,java,java手写操作日志功能)