package com.linln.common.utils;@b@@b@import org.springframework.beans.BeanUtils;@b@import org.springframework.beans.BeansException;@b@import org.springframework.beans.FatalBeanException;@b@import org.springframework.lang.Nullable;@b@import org.springframework.util.Assert;@b@import org.springframework.util.ClassUtils;@b@@b@import javax.persistence.Id;@b@import java.beans.PropertyDescriptor;@b@import java.lang.reflect.Field;@b@import java.lang.reflect.InvocationTargetException;@b@import java.lang.reflect.Method;@b@import java.lang.reflect.Modifier;@b@import java.util.Arrays;@b@import java.util.List;@b@@b@/**@b@ * 实体对象操作工具@b@ *@b@ * @author 小懒虫@b@ * @date 2018/10/15@b@ */@b@public class EntityBeanUtil {@b@@b@ /** 复制实体对象保留的默认字段 */@b@ private static String[] defaultFields = new String[]{@b@ "createDate",@b@ "updateDate",@b@ "createBy",@b@ "updateBy",@b@ "status"@b@ };@b@@b@ /**@b@ * 获取实体对象ID字段值@b@ *@b@ * @param entity 实体对象@b@ * @return [0]为ID字段名,[1]为ID字段值@b@ */@b@ public static Object[] getId(Object entity) {@b@ Field[] fields = entity.getClass().getDeclaredFields();@b@ for (Field field : fields) {@b@ Id id = field.getAnnotation(Id.class);@b@ if (id != null) {@b@ try {@b@ field.setAccessible(true);@b@ return new Object[]{field.getName(), field.get(entity)};@b@ } catch (IllegalAccessException e) {@b@ throw new FatalBeanException(@b@ "获取" + entity.getClass().getName() + "实体对象主键出错!", e);@b@ }@b@ }@b@ }@b@ return null;@b@ }@b@@b@ /**@b@ * 根据字段名获取实体对象值@b@ *@b@ * @param entity 实体对象@b@ * @param fieldName 字段名@b@ * @return Object对象@b@ */@b@ public static Object getField(Object entity, String fieldName) throws InvocationTargetException, IllegalAccessException {@b@ PropertyDescriptor beanObjectPd = BeanUtils.getPropertyDescriptor(entity.getClass(), fieldName);@b@ if (beanObjectPd != null) {@b@ Method readMethod = beanObjectPd.getReadMethod();@b@ if (readMethod != null) {@b@ if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {@b@ readMethod.setAccessible(true);@b@ }@b@ return readMethod.invoke(entity);@b@ }@b@ }@b@ return null;@b@ }@b@@b@ /**@b@ * 根据字段名获取实体对象值@b@ *@b@ * @param entity 实体对象@b@ * @param fieldName 字段名@b@ * @param value 字段值@b@ */@b@ public static void setField(Object entity, String fieldName, Object value) throws InvocationTargetException, IllegalAccessException {@b@ PropertyDescriptor beanObjectPd = BeanUtils.getPropertyDescriptor(entity.getClass(), fieldName);@b@ if (beanObjectPd != null) {@b@ Method writeMethod = beanObjectPd.getWriteMethod();@b@ if (writeMethod != null) {@b@ if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {@b@ writeMethod.setAccessible(true);@b@ }@b@ writeMethod.invoke(entity, value);@b@ }@b@ }@b@ }@b@@b@ /**@b@ * 复制实体对象指定字段的数据,复制默认字段数据@b@ * {用于保留部分原始数据}@b@ *@b@ * @param source 源对象@b@ * @param target 目标对象@b@ */@b@ public static void copyProperties(Object source, Object target) throws BeansException {@b@ EntityBeanUtil.copyProperties(source, target, null, defaultFields);@b@ }@b@@b@ /**@b@ * 复制实体对象指定字段的数据,复制自定义的字段数据@b@ * {用于保留部分原始数据}@b@ *@b@ * @param source 源对象@b@ * @param target 目标对象@b@ * @param fields 需要保留的自定义字段@b@ */@b@ public static void copyProperties(Object source, Object target, String... fields) throws BeansException {@b@ // 合并两个数组@b@ String[] jointRetainProperties = new String[defaultFields.length + fields.length];@b@ System.arraycopy(defaultFields, 0, jointRetainProperties, 0, defaultFields.length);@b@ System.arraycopy(fields, 0, jointRetainProperties, defaultFields.length, fields.length);@b@ EntityBeanUtil.copyProperties(source, target, null, jointRetainProperties);@b@ }@b@@b@ /**@b@ * 复制实体对象指定字段的数据@b@ * {用于保留部分原始数据}@b@ * {代码基于BeanUtils.copyProperties(...)}@b@ *@b@ * @param source 源对象@b@ * @param target 目标对象@b@ * @param editable 将字段设置限制为的类(或接口)@b@ * @param fields 需要保留的自定义字段@b@ */@b@ private static void copyProperties(Object source, Object target, @Nullable Class<?> editable,@b@ @Nullable String... fields) throws BeansException {@b@@b@ Assert.notNull(source, "Source must not be null");@b@ Assert.notNull(target, "Target must not be null");@b@@b@ Class<?> actualEditable = target.getClass();@b@ if (editable != null) {@b@ if (!editable.isInstance(target)) {@b@ throw new IllegalArgumentException("Target class [" + target.getClass().getName() +@b@ "] not assignable to Editable class [" + editable.getName() + "]");@b@ }@b@ actualEditable = editable;@b@ }@b@ PropertyDescriptor[] targetPds = BeanUtils.getPropertyDescriptors(actualEditable);@b@ List<String> ignoreList = (fields != null ? Arrays.asList(fields) : null);@b@@b@ for (PropertyDescriptor targetPd : targetPds) {@b@ Method writeMethod = targetPd.getWriteMethod();@b@ if (writeMethod != null && (ignoreList == null || ignoreList.contains(targetPd.getName()))) {@b@ PropertyDescriptor sourcePd = BeanUtils.getPropertyDescriptor(source.getClass(), targetPd.getName());@b@ if (sourcePd != null) {@b@ Method readMethod = sourcePd.getReadMethod();@b@ if (readMethod != null &&@b@ ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType())) {@b@ try {@b@ if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {@b@ readMethod.setAccessible(true);@b@ }@b@ Object value = readMethod.invoke(source);@b@ if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {@b@ writeMethod.setAccessible(true);@b@ }@b@ writeMethod.invoke(target, value);@b@ } catch (Throwable ex) {@b@ throw new FatalBeanException(@b@ "Could not copy property '" + targetPd.getName() + "' from source to target", ex);@b@ }@b@ }@b@ }@b@ }@b@ }@b@ }@b@@b@ /**@b@ * 复制实体对象数据,忽略默认字段数据@b@ * {用于忽略部分原始数据,功能与copyProperties相反}@b@ *@b@ * @param source 源对象@b@ * @param target 目标对象@b@ */@b@ public static void copyPropertiesIgnores(Object source, Object target) {@b@ BeanUtils.copyProperties(source, target, defaultFields);@b@ }@b@@b@ /**@b@ * 复制实体对象数据,忽略默认字段数据@b@ * {用于忽略部分原始数据,功能与copyProperties相反}@b@ *@b@ * @param source 源对象@b@ * @param target 目标对象@b@ * @param ignoreProperties 需要忽略的自定义字段@b@ */@b@ public static void copyPropertiesIgnores(Object source, Object target, String... ignoreProperties) {@b@ // 合并两个数组@b@ String[] jointIgnoreProperties = new String[defaultFields.length + ignoreProperties.length];@b@ System.arraycopy(defaultFields, 0, jointIgnoreProperties, 0, defaultFields.length);@b@ System.arraycopy(ignoreProperties, 0, jointIgnoreProperties, defaultFields.length, ignoreProperties.length);@b@ BeanUtils.copyProperties(source, target, jointIgnoreProperties);@b@ }@b@@b@ /**@b@ * 克隆一个新的bean对象@b@ *@b@ * @param object 源对象@b@ */@b@ public static Object cloneBean(Object object) {@b@ return cloneBean(object, (String[]) null);@b@ }@b@@b@ /**@b@ * 克隆一个新的bean对象,忽略部分字段@b@ *@b@ * @param object 源对象@b@ * @param ignoreProperties 需要忽略的字段@b@ */@b@ public static Object cloneBean(Object object, String... ignoreProperties) {@b@ Object cloneObject = null;@b@ if (object != null) {@b@ try {@b@ cloneObject = object.getClass().newInstance();@b@ BeanUtils.copyProperties(object, cloneObject, ignoreProperties);@b@ } catch (InstantiationException | IllegalAccessException e) {@b@ e.printStackTrace();@b@ }@b@ }@b@ return cloneObject;@b@ }@b@}