Helius
2020-12-09 660fba5b40303dd661afcc2e2bd54a18d4f53c5c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
/**
 * 
 */
package com.matrix.core.tools;
 
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
 
import org.apache.commons.lang.ObjectUtils;
import org.springframework.util.CollectionUtils;
 
import com.matrix.core.anotations.Extend;
import com.matrix.core.pojo.EntityDTO;
 
/**
 * 数据库模型的处理类
 * 
 * @author JIANGYOUYAO
 * @email 935090232@qq.com
 * @date 2017年11月29日
 */
public class ModelUtils {
 
    private static final String TYPE = "TYPE";
 
    /**
     * 比较新旧POJO对象,将修改过的值和字段名放入Map中
     * 
     * @param oldObj
     * @param newObj
     * @return
     * @throws NoSuchMethodException
     * @throws SecurityException
     * @throws IllegalAccessException
     * @throws IllegalArgumentException
     * @throws InvocationTargetException
     * @throws NoSuchFieldException
     */
    @SuppressWarnings("unchecked")
    public static final Map<String, Object> comparePojo2Map(Object oldObj, Object newObj)
                throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException,
            InvocationTargetException, NoSuchFieldException {
        Map<String, Object> map = new HashMap<>(60);
        Class<Object> oldClazz = (Class<Object>) oldObj.getClass();
        Field[] fields = oldClazz.getDeclaredFields();
        List<Field> fieldList = new ArrayList<>(60);
        Class<Object> newClazz = (Class<Object>) newObj.getClass();
        if (oldObj instanceof EntityDTO) {
            fieldList.add(EntityDTO.class.getDeclaredField("updateBy"));
        }
        CollectionUtils.mergeArrayIntoCollection(fields, fieldList);
        for (Field field : fieldList) {
            if (field.getAnnotation(Extend.class) != null || Modifier.isStatic(field.getModifiers())) {
                continue;
            }
            String getMethodName = "get" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1);
            Method oldM = (Method) oldClazz.getMethod(getMethodName);
            Method newM = (Method) newClazz.getMethod(getMethodName);
            // 如果新旧的值不相等
            if (newM.invoke(newObj) != null && !ObjectUtils.equals(oldM.invoke(oldObj), newM.invoke(newObj))) {
                map.put(field.getName(), newM.invoke(newObj));
            }
        }
        return map;
    }
 
    /**
     * 
     *  判断值是否被修改过
     * @author:姜友瑶
     * @param oldObj
     * @param newObj
     * @return 返回类型 boolean
     * @throws NoSuchFieldException
     * @date 2016年11月11日
     */
    @SuppressWarnings({ "unchecked" })
    public static boolean isModified(Object oldObj, Object newObj) throws NoSuchFieldException {
        if (oldObj == newObj) {
            return true;
        }
        if (oldObj == null || newObj == null) {
            return false;
        }
        try {
            Class<Object> oldClazz = (Class<Object>) oldObj.getClass();
            Field[] fields = oldClazz.getDeclaredFields();
            Class<Object> newClazz = (Class<Object>) newObj.getClass();
            List<Field> fieldList = new ArrayList<>(60);
            if (oldObj instanceof EntityDTO) {
                fieldList.add(EntityDTO.class.getDeclaredField("updateBy"));
            }
            CollectionUtils.mergeArrayIntoCollection(fields, fieldList);
            // 依次比较所有可以Modify的字段
            for (Field field : fieldList) {
                // 不是可以修改的字段
                if (field.getAnnotation(Extend.class) != null) {
                    continue;
                }
                String getMethodName = "get" + field.getName().substring(0, 1).toUpperCase()
                        + field.getName().substring(1);
                Method oldM = (Method) oldClazz.getMethod(getMethodName);
                Method newM = (Method) newClazz.getMethod(getMethodName);
                if (isPrimitive(field) || String.class == field.getType() || Date.class == field.getType()
                        || field.getType().isEnum()) {
                    // 如果字段是基本类型,封装类型,以及String, Date, 枚举,则直接进行比较
                    // 如果新旧的值不相等
                    if (!ObjectUtils.equals(oldM.invoke(oldObj), newM.invoke(newObj))) {
                        return true;
                    }
                } else if (field.getType().isAssignableFrom(List.class)) {
                    // 如果是List
                    if (isModifiedList((List<Object>) oldM.invoke(oldObj), (List<Object>) newM.invoke(newObj))) {
                        return true;
                    }
                } else {
                    // 其他类型暂时不支持
                    throw new RuntimeException("暂时不支持这种类型的修改判断:" + field.getType());
                }
            }
            return false;
        } catch (SecurityException | NoSuchMethodException | IllegalAccessException | IllegalArgumentException
                | InvocationTargetException e) {
            throw new RuntimeException(e);
        }
    }
 
    @SuppressWarnings("rawtypes")
    private static boolean isPrimitive(Field field)
            throws IllegalArgumentException, IllegalAccessException, SecurityException {
        if (field.getType().isPrimitive()) {
            return true;
        }
        try {
            if (((Class) field.getType().getField(TYPE).get(null)).isPrimitive()) {
                return true;
            }
            return false;
        } catch (NoSuchFieldException e) {
            return false;
        }
    }
 
    public static boolean isModifiedList(final Collection<Object> list1, final Collection<Object> list2)
            throws NoSuchFieldException {
        if (list1 == list2) {
            return false;
        }
        if (list1 == null || list2 == null || list1.size() != list2.size()) {
            return true;
        }
        Iterator<Object> it1 = list1.iterator();
        Iterator<Object> it2 = list2.iterator();
        Object obj1 = null;
        Object obj2 = null;
        while (it1.hasNext() && it2.hasNext()) {
            obj1 = it1.next();
            obj2 = it2.next();
 
            if (isModified(obj1, obj2)) {
                return true;
            }
        }
        return it1.hasNext() || it2.hasNext();
    }
 
}