/**
|
*
|
*/
|
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();
|
}
|
|
}
|