1、操作对象工具 MyBeanUtils

package com.nrxt.nms.mon.pt.cascade.utils;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.FatalBeanException;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;

/**
 * 操作对象工具
 */
public class MyBeanUtils extends BeanUtils {
    private static final Logger logger = LoggerFactory.getLogger(BeanUtils.class);
    private static final String SERIAL_VERSION_UID = "serialVersionUID";
    private static final String INTEGER = "java.lang.Integer";
    private static final String STRING = "java.lang.String";

    /**
     * Copy properties.
     *
     * @param source the source
     * @param target the target
     * @throws BeansException the beans exception
     */
    public static void copyProperties(Object source, Object target) throws BeansException {
        copyProperties(source, target, null, (String[]) null);
    }

    private static void copyProperties(Object source, Object target, Class<?> editable, String... ignoreProperties)
            throws BeansException {

        Assert.notNull(source, "Source must not be null");
        Assert.notNull(target, "Target must not be null");

        Class<?> actualEditable = target.getClass();
        if (editable != null) {
            if (!editable.isInstance(target)) {
                throw new IllegalArgumentException("Target class [" + target.getClass().getName()
                        + "] not assignable to Editable class [" + editable.getName() + "]");
            }
            actualEditable = editable;
        }
        PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);
        List<String> ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties) : null);

        for (PropertyDescriptor targetPd : targetPds) {
            Method writeMethod = targetPd.getWriteMethod();
            if (writeMethod == null) {
                continue;
            }
            if (ignoreList == null || !ignoreList.contains(targetPd.getName())) {
                PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());
                if (sourcePd != null) {
                    Method readMethod = sourcePd.getReadMethod();
                    if (readMethod != null &&
                            ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType())) {
                        try {
                            if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
                                readMethod.setAccessible(true);
                            }
                            Object value = readMethod.invoke(source);
                            // 这里判断以下value是否为空 当然这里也能进行一些特殊要求的处理 例如绑定时格式转换等等
                            if (value != null) {
                                if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
                                    writeMethod.setAccessible(true);
                                }
                                writeMethod.invoke(target, value);
                            }
                        } catch (Throwable ex) {
                            throw new FatalBeanException(
                                    "Could not copy property '" + targetPd.getName() + "' from source to target", ex);
                        }
                    }
                }
            }
        }
    }


    /**
     * 复制对象
     *
     * @param <T>       the type parameter
     * @param entity    the entity
     * @param targetCls the target cls
     * @return t t
     */
    public static <T> T copyObject(Object entity, Class<? extends T> targetCls) {
        // 如果entity,直接返回null
        if (entity == null) {
            return null;
        }
        Object target = null;
        try {
            target = targetCls.newInstance();
            copyProperties(entity, target);
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return (T) target;
    }

    /**
     * 复制对象
     *
     * @param list      the list
     * @param targetCls the target cls
     * @return list list
     */
    public static <T> List<T> copyList(List list, Class<? extends T> targetCls) {
        List<T> resultList = new ArrayList();
        if (list != null && list.size() > 0) {
            for (Object entity : list) {
                resultList.add(copyObject(entity, targetCls));
            }
        }
        return resultList;
    }


    /**
     * java反射bean的get方法
     *
     * @param objectClass the object class
     * @param fieldName   the field name
     * @return get method
     */
    @SuppressWarnings("unchecked")
    public static Method getGetMethod(Class objectClass, String fieldName) {
        if (objectClass != null && StringUtils.isNotBlank(fieldName)) {
            StringBuffer sb = new StringBuffer();
            sb.append("get");
            sb.append(fieldName.substring(0, 1).toUpperCase());
            sb.append(fieldName.substring(1));
            try {
                return objectClass.getMethod(sb.toString());
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
                logger.error("error:{}", e);
            }
        }
        return null;
    }


    /**
     * java反射bean的set方法
     *
     * @param objectClass the object class
     * @param fieldName   the field name
     * @return set method
     */
    @SuppressWarnings("unchecked")
    public static Method getSetMethod(Class objectClass, String fieldName) {
        try {
            Class[] parameterTypes = new Class[1];
            Field field = objectClass.getDeclaredField(fieldName);
            parameterTypes[0] = field.getType();
            StringBuffer sb = new StringBuffer();
            sb.append("set");
            sb.append(fieldName.substring(0, 1).toUpperCase());
            sb.append(fieldName.substring(1));
            Method method = objectClass.getMethod(sb.toString(), parameterTypes);
            return method;
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("error:{}", e);
        }
        return null;
    }


    /**
     * 执行set方法
     *
     * @param o         执行对象
     * @param fieldName 属性
     * @param value     值
     */
    public static void invokeSet(Object o, String fieldName, Object value) {
        Method method = getSetMethod(o.getClass(), fieldName);
        if (method != null) {
            try {
                method.invoke(o, new Object[]{value});
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("error:{}", e);
            }
        }
    }


    /**
     * Invoke set string int.
     *
     * @param o         the o
     * @param fieldName <br>
     * @param value     the value
     * @return <br>
     * @throws <br>
     * @describe 这个函数主要用于将字符串和数字型分开 前台都是字符串 根据model类型转换 现在仅支持String int 不是这两个类型不做set函数<br>
     */
    public static void invokeSetStringInt(Object o, String fieldName, String value) {
        Method method = getGetMethod(o.getClass(), fieldName);
        if (method != null) {
            String type = method.getReturnType().getName();
            if (INTEGER.equals(type)) {
                invokeSet(o, fieldName, (value == null) ? null : Integer.parseInt(value));
            } else if (STRING.equals(type)) {
                invokeSet(o, fieldName, value);
            } else {
                logger.error("set 函数不能设置Sting和int以外的函数,设置类型:" + type + ",方法:" + method.getName());
            }
        }
    }

    /**
     * 执行get方法
     *
     * @param o         执行对象
     * @param fieldName 属性
     * @return the object
     */
    public static Object invokeGet(Object o, String fieldName) {
        Method method = getGetMethod(o.getClass(), fieldName);
        if (method != null) {
            try {
                return method.invoke(o, new Object[0]);
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("error:{}", e);
            }
        }
        return null;
    }

    /**
     * Invoke get string string.
     *
     * @param o         the o
     * @param fieldName the field name
     * @return <br>
     * @throws <br>
     * @describe 将返回值包装成String 如果是空则仍然保持空  <br>
     */
    public static String invokeGetString(Object o, String fieldName) {
        Object obj = invokeGet(o, fieldName);
        return (obj == null) ? null : String.valueOf(obj);
    }


    /**
     * Merger obj object.
     *
     * @param <T>      项目域对象如果为空,则直接返回产品域对象                 项目域对象字段属性为空,则使用产品域覆盖项目域字段
     * @param parent   产品域对象
     * @param son      项目域对象
     * @param refClass class对象
     * @return the object
     */
    public static <T> Object mergerObj(T parent, T son, Class<?> refClass) {
        logger.debug(">>>>>>>>>>>>>>>>>>>mergerObj");
        logger.debug("Product object:" + parent);
        logger.debug("Project object:" + son);
        Object obj = null;
        try {
            obj = refClass.newInstance();
            if (parent == null) {
                obj = son;
            } else if (son == null) {
                obj = parent;
            } else {
                for (Field field : refClass.getDeclaredFields()) {
                    String fieldName = field.getName();
                    if (SERIAL_VERSION_UID.equalsIgnoreCase(fieldName)) {
                        continue;
                    }
                    Object value = invokeGet(son, fieldName);
                    if (value == null) {
                        value = invokeGet(parent, fieldName);
                    }
                    invokeSet(obj, fieldName, value);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("error:{}", e);
            ;
        }
        logger.debug("Page object:" + obj);
        return obj;
    }


    /**
     * Merger obj object.
     *
     * @param <T>            the type parameter
     * @param parent         the parent
     * @param son            the son
     * @param refClassParent the ref class parent
     * @param refClassSon    the ref class son
     * @return the object
     */
    public static <T> Object mergerObj(T parent, T son, Class<?> refClassParent, Class<?> refClassSon) {
        return mergerObj(parent, son, refClassParent, refClassSon, null);
    }


    /**
     * Merger obj object.
     *
     * @param <T>            父对象为空,则直接返回子对象                       子对象为空,则将子对象域父对象相同的字段拷贝给obj                       父对象与子对象都不为空,现将子对象的值拷贝给obj,在将子对象与父对象相同的字段拷贝给obj,                       <p/>                       例如:比如指标与业务视图字段合并,则指标为父对象、业务视图字段为子对象                       <p/>                       变量命名有问题
     * @param parent         父对象
     * @param son            子对象
     * @param refClassParent 父class对象
     * @param refClassSon    子class对象
     * @param prefix         前缀
     * @return the object
     */
    public static <T> Object mergerObj(T parent, T son, Class<?> refClassParent, Class<?> refClassSon, String prefix) {
        logger.debug(">>>>>>>>>>>>>>>>>>>mergerObj");
        logger.debug("Parent object:" + parent);
        logger.debug("Son object:" + son);
        Map<String, String> publicFieldMap = new HashMap<String, String>(16);
        Object obj = null;
        try {
            /**
             * 比较父class对象与子class对象,找出字段相同的字段
             */
            for (Field pField : refClassParent.getDeclaredFields()) {
                String pFieldName = pField.getName();
                for (Field sField : refClassSon.getDeclaredFields()) {
                    String sFieldName = sField.getName();
                    if (sFieldName.equals(pFieldName)) {
                        publicFieldMap.put(pFieldName, sFieldName);
                        break;
                    } else if (prefix != null && sFieldName.equals(prefix + pFieldName)) {
                        publicFieldMap.put(pFieldName, sFieldName);
                        break;
                    }
                }
            }

            obj = refClassSon.newInstance();
            //父对象为空,直接返回父对象给obj
            if (parent == null) {
                obj = son;
            } else
                //子对象为空,将父对象中与子对象中相同字段的值复制给obj
                if (son == null) {
                    for (Map.Entry<String, String> entry : publicFieldMap.entrySet()) {
                        String pFieldName = entry.getKey();
                        String sFieldName = entry.getValue();
                        if (SERIAL_VERSION_UID.equalsIgnoreCase(sFieldName)) {
                            continue;
                        }
                        Object value = invokeGet(parent, sFieldName);
                        invokeSet(obj, sFieldName, value);
                    }
                } else {
                    //先将子对象拷贝给obj
                    for (Field field : refClassSon.getDeclaredFields()) {
                        String fieldName = field.getName();
                        if (SERIAL_VERSION_UID.equalsIgnoreCase(fieldName)) {
                            continue;
                        }
                        Object value = invokeGet(son, fieldName);
                        invokeSet(obj, fieldName, value);
                    }
                    //将相同字段的值拷贝给obj
                    for (Map.Entry<String, String> entry : publicFieldMap.entrySet()) {
                        String pFieldName = entry.getKey();
                        String sFieldName = entry.getValue();
                        if (SERIAL_VERSION_UID.equalsIgnoreCase(sFieldName)) {
                            continue;
                        }
                        Object value = invokeGet(son, sFieldName);
                        if (null == value || "".equals(value)) {
                            value = invokeGet(parent, pFieldName);
                        }
                        invokeSet(obj, sFieldName, value);
                    }
                }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("error:{}", e);
            ;
        }
        logger.debug("Merge object:" + obj);
        return obj;
    }


    /**
     * Division obj t.
     *
     * @param <T>      the type parameter
     * @param parent   父对象
     * @param son      子对象
     * @param newSon   新的子对象
     * @param refClass class对象
     * @return T t
     */
    public static <T> T divisionObj(T parent, T son, T newSon, Class<?> refClass) {
        logger.debug(">>>>>>>>>>>>>>>>>>>divisionObj");
        logger.debug("Product object:" + parent);
        logger.debug("Project object:" + son);
        logger.debug("Page object:" + newSon);
        for (Field field : refClass.getDeclaredFields()) {
            String filedName = field.getName();
            if (SERIAL_VERSION_UID.equalsIgnoreCase(filedName)) {
                continue;
            }
            /*项目域不存在,则说明该元素只是项目化没有修改,表里面不存在*/
            Object valueSon = (son == null) ? null : invokeGet(son, filedName);
            /*子对象的对应的属性为空,则继承与产品域的属性,如果没有修改则继续继承*/
            if (valueSon == null) {
                Object valueNewSon = invokeGet(newSon, filedName);
                Object valueParent = invokeGet(parent, filedName);
                if (valueParent != null && valueParent.equals(valueNewSon)) {
                    invokeSet(newSon, filedName, null);
                }
            }
        }
        logger.debug("New object:" + newSon);
        return newSon;
    }


    /**
     * 比较产品域对象、项目域对象、页面对象,返回最后需要插入数据库中的对象
     *
     * @param <T>           the type parameter
     * @param parent        父对象
     * @param son           子对象
     * @param newSon        新的子对象
     * @param refClass      class对象
     * @param excludeFields 不需要比较字段的列表
     * @return T t
     */
    public static <T> T divisionObj(T parent, T son, T newSon, Class<?> refClass, String... excludeFields) {
        logger.debug(">>>>>>>>>>>>>>>>>>>divisionObj");
        logger.debug("Product object:" + parent);
        logger.debug("Project object:" + son);
        logger.debug("Page object:" + newSon);
        logger.debug("ExcludeFields:" + excludeFields);


        for (Field field : refClass.getDeclaredFields()) {
            String filedName = field.getName();
            if (SERIAL_VERSION_UID.equalsIgnoreCase(filedName)) {
                continue;
            }
            //排除不需要比较的字段
            if (Arrays.asList(excludeFields).contains(filedName)) {
                continue;
            }
            /*项目域不存在,则说明该元素只是项目化没有修改,表里面不存在*/
            Object valueSon = (son == null) ? null : invokeGet(son, filedName);
            /*子对象的对应的属性为空,则继承与产品域的属性,如果没有修改则继续继承*/
            if (valueSon == null) {
                Object valueNewSon = invokeGet(newSon, filedName);
                Object valueParent = invokeGet(parent, filedName);
                if (valueParent != null && valueParent.equals(valueNewSon)) {
                    invokeSet(newSon, filedName, null);
                }
            }
        }
        logger.debug("New object:" + newSon);
        return newSon;
    }

    /**
     * 应用场景,产品域字段列表跟项目域字段列表合并,
     * 以keyName作为主键,
     * 相同的keyName,则使用项目域的覆盖产品域的
     *
     * @param <T>        the type parameter
     * @param parentList 父域列表
     * @param sonList    子域列表
     * @param keyName    主键
     * @return list list
     */
    public static <T> List<T> mergerList(List<T> parentList, List<T> sonList, String keyName) {
        logger.debug(">>>>>>>>>>>>>>>>>>>mergerObj");
        logger.debug("Product object list:" + parentList);
        logger.debug("Project object list:" + sonList);
        logger.debug("keyName :" + keyName);

        List<T> resultList = new ArrayList<T>();
        Map<Object, T> map = new HashMap<Object, T>(16);
        if (parentList == null) {
            resultList.addAll(sonList);
            return resultList;
        }
        if (sonList == null) {
            resultList.addAll(parentList);
            return resultList;
        }
        resultList.addAll(parentList);
        for (T obj : parentList) {
            Object keyFieldName = invokeGet(obj, keyName);
            map.put(keyFieldName, obj);
        }
        int size = sonList.size();
        for (int i = 0; i < size; i++) {
            Object keyFieldName = invokeGet(sonList.get(i), keyName);
            if (map.containsKey(keyFieldName)) {
                resultList.remove(map.get(keyFieldName));
                resultList.add(i, sonList.get(i));
            } else {
                resultList.add(sonList.get(i));
            }
        }
        logger.debug("Page object list:" + sonList);
        return resultList;
    }

    /**
     * Get all field name string [ ].
     *
     * @param <T>      the type parameter
     * @param refClass <br>
     * @return <br>
     * @throws <br>
     * @describe 返回dto的所有属性字段名称 返回其中所有字段(除serialVersionUID之外) 可以用于设置值  <br>
     */
    public static <T> String[] getAllFieldName(Class<?> refClass) {
        Field[] allField = refClass.getDeclaredFields();
        List<String> allFieldList = new ArrayList<String>();
        for (int i = 0, j = 0; i < allField.length; i++) {
            String filedName = allField[i].getName();
            if (!SERIAL_VERSION_UID.equalsIgnoreCase(filedName)) {
                allFieldList.add(filedName);
            }
        }
        return allFieldList.toArray(new String[allFieldList.size()]);
    }

    /**
     * Get all field field [ ].
     *
     * @param <T>      the type parameter
     * @param refClass <br>
     * @return <br>
     * @throws <br>
     * @describe 返回dto的所有Field字段 返回其中所有字段(除serialVersionUID之外) 可以用于设置值  <br>
     */
    public static <T> Field[] getAllField(Class<?> refClass) {
        Field[] allField = refClass.getDeclaredFields();
        List<Field> allFieldList = new ArrayList<Field>();
        for (int i = 0, j = 0; i < allField.length; i++) {
            if (!SERIAL_VERSION_UID.equalsIgnoreCase(allField[i].getName())) {
                allFieldList.add(allField[i]);
            }
        }
        return allFieldList.toArray(new Field[allFieldList.size()]);
    }


    /**
     * 获取指定字段名称查找在class中的对应的Field对象(包括查找父类)
     *
     * @param clazz     指定的class
     * @param fieldName 字段名称
     * @return Field对象 class field
     */
    public static Field getClassField(Class clazz, String fieldName) {
        if (Object.class.getName().equals(clazz.getName())) {
            return null;
        }
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field field : declaredFields) {
            if (field.getName().equals(fieldName)) {
                return field;
            }
        }

        Class superClass = clazz.getSuperclass();
        if (superClass != null) {
            // 简单的递归一下
            return getClassField(superClass, fieldName);
        }
        return null;
    }


    /**
     * 求ls对ls2的差集,即ls中有,但ls2中没有的
     *
     * @param ls  the ls
     * @param ls2 the ls 2
     * @return list list
     */
    public static List diff(List ls, List ls2) {
        List list = new ArrayList(Arrays.asList(new Object[ls.size()]));
        Collections.copy(list, ls);
        list.removeAll(ls2);
        return list;
    }

    /**
     * 求2个集合的交集
     *
     * @param ls  the ls
     * @param ls2 the ls 2
     * @return list list
     */
    public static List intersect(List ls, List ls2) {
        List list = new ArrayList(Arrays.asList(new Object[ls.size()]));
        Collections.copy(list, ls);
        list.retainAll(ls2);
        return list;
    }

    /**
     * 求2个集合的并集
     *
     * @param ls  the ls
     * @param ls2 the ls 2
     * @return list list
     */
    public static List union(List ls, List ls2) {
        List list = new ArrayList(Arrays.asList(new Object[ls.size()]));
        //将ls的值拷贝一份到list中
        Collections.copy(list, ls);
        list.removeAll(ls2);
        list.addAll(ls2);
        return list;
    }
}

2、实体类 

  • NmsAppDO
package com.nrxt.nms.mon.pt.cascade.entity;

import lombok.Data;

import javax.persistence.Column;

@Data
public class NmsAppDO {
    @Column(name = "CI_ID")
    String ciId;

    @Column(name = "CI_NAME")
    String ciName;

    @Column(name = "APPID")
    String appId;

    @Column(name = "BGCODE")
    String bgCode;

    @Column(name = "PROVID")
    String provId;

    @Column(name = "APPRATE")
    String appRate;

    @Column(name = "CLOUDFLAG")
    String cloudFlag;

    @Column(name = "OM_APP")
    String omApp;

    @Column(name = "SHORT_NAME")
    String shortName;

    @Column(name = "PUSH_TYPE")
    String pushType;

    @Column(name = "NETREGION")
    String netregion;

    @Column(name = "REPAIR_STATE")
    String repairState;

    @Column(name = "RUN_USER_TEL")
    String runUserTel;

    @Column(name = "SYSTEM_TYPE")
    String systemType;

    @Column(name = "IS_MONITOR")
    String isMonitor;

    @Column(name = "IS_APPFUNCINST")
    String isAppfuncinst;

    @Column(name = "IS_APMSERVICE")
    String isApmservice;

    @Column(name = "RUN_STATUS")
    String runStatus;

    @Override
    public String toString() {
        return String.format("BGCODE=%s,CI_ID=%s,APPID=%s", bgCode, ciId, appId);
    }
}
  • NmsAppMonitorDO 
package com.nrxt.nms.mon.pt.cascade.entity;

import com.nrxt.nms.mon.pt.cascade.utils.DateUtils;
import lombok.Data;

import javax.persistence.Column;

@Data
public class NmsAppMonitorDO {

    public NmsAppMonitorDO(){
        this.monitorStatus = "0";
        this.deletedFlag = "N";
        this.createdAt = DateUtils.getLocalDateTime();
        this.updatedAt = DateUtils.getLocalDateTime();
    }

    @Column(name = "CI_ID")
    private String ciId;

    @Column(name = "APP_ID")
    private String appId;

    @Column(name = "APP_NAME")
    private String ciName;

    @Column(name = "APP_SHORT_NAME")
    private String shortName;

    @Column(name = "APP_RATE")
    private String appRate;

    @Column(name = "PUSH_TYPE")
    private String pushType;

    @Column(name = "NETREGION")
    private String netregion;

    @Column(name = "RUN_STATUS")
    private String runStatus;

    @Column(name = "MONITOR_STATUS")
    private String monitorStatus;

    @Column(name = "DELETED_FLAG")
    private String deletedFlag;

    @Column(name = "CREATED_AT")
    private String createdAt;

    @Column(name = "UPDATED_AT")
    private String updatedAt;

    @Column(name = "TOTAL")
    private Integer total;

}

3、工具类使用

List<NmsAppMonitorDO> nmsAppMonitorDOList = MyBeanUtils.copyList(nmsAppDOList,NmsAppMonitorDO.class);

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐