/** * */ 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 comparePojo2Map(Object oldObj, Object newObj) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException { Map map = new HashMap<>(60); Class oldClazz = (Class) oldObj.getClass(); Field[] fields = oldClazz.getDeclaredFields(); List fieldList = new ArrayList<>(60); Class newClazz = (Class) 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 oldClazz = (Class) oldObj.getClass(); Field[] fields = oldClazz.getDeclaredFields(); Class newClazz = (Class) newObj.getClass(); List 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) oldM.invoke(oldObj), (List) 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 list1, final Collection list2) throws NoSuchFieldException { if (list1 == list2) { return false; } if (list1 == null || list2 == null || list1.size() != list2.size()) { return true; } Iterator it1 = list1.iterator(); Iterator 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(); } }