java两个实体类相同属性的复制
【代码】java两个实体类相同属性的复制。
·
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);
更多推荐
所有评论(0)