一、使用背景:
pom依賴:
<!-- https://mvnrepository.com/artifact/commons-io/commons-io --> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.6</version> </dependency> <!-- https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils-core --> <dependency> <groupId>commons-beanutils</groupId> <artifactId>commons-beanutils-core</artifactId> <version>1.8.3</version> </dependency> <!-- https://mvnrepository.com/artifact/net.sf.dozer/dozer --> <dependency> <groupId>net.sf.dozer</groupId> <artifactId>dozer</artifactId> <version>5.5.1</version> </dependency>
二、BeanUtils公用類:
package com.dongl.utils; import org.dozer.DozerBeanMapper; import org.springframework.beans.BeansException; import org.springframework.beans.FatalBeanException; import org.springframework.util.Assert; import org.springframework.util.StringUtils; import java.beans.PropertyDescriptor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.*; /** * @author D-L * @Classname BeanUtils * @Version 1.0 * @Description 通過無參數實例化對象和復制屬性值的方式 * 完成實體類之間的轉換 * 完成map->實體類 * 實體類->map * 基於Dozer轉換對象的類型 * 對bean的特定屬性賦值 * @Date 2020/8/5 */ public class BeanUtils extends org.springframework.beans.BeanUtils{ /** * 持有Dozer單例, 避免重復創建DozerMapper消耗資源. */ private static DozerBeanMapper dozer = new DozerBeanMapper(); /** * 通過無參數實例化目標對象和復制屬性,將POJO對象轉換成相應的對象 * * @param source 原對象 * @param type 目標類型 * @return 轉換后的對象 */ public static <T> T convert(Object source, Class<T> type) { T target = instantiateClass(type); if (source == null) { return target; } copyProperties(source, target); return target; } /** * 通過無參數實例化目標對象和復制屬性,將兩個POJO對象按照順序轉換成相應的對象 * 如果原對象有相同的屬性 會出現屬性值覆蓋 * @param source1 原對象1 * @param source2 原對象2 * @param type 目標類型 * @param <T> * @return 返回轉換后的對象 */ public static <T> T converts(Object source1, Object source2, Class<T> type) { T target = instantiateClass(type); if (source1 == null && source2 == null) { return target; } copyProperties(source1, target); copyProperties(source2, target); return target; } /** * 通過無參數實例化目標對象和復制屬性,將POJO對象轉換成相應的對象,可忽略部分屬性 * @param source 原對象 * @param type 目標類型 * @param ignoreProperties 忽略的屬性列表 * @return 轉換后的對象 */ public static <T> T convert(Object source, Class<T> type, String[] ignoreProperties) { T target = instantiateClass(type); copyProperties(source, target, ignoreProperties); return target; } /** * 通過無參數實例化目標對象和復制屬性,將POJO對象批量轉換成指定類型的對象 * @param sources List 原對象列表 * @param type 目標類型 * @return List 目標類型對象列表 */ public static <T, E> List<T> convert(List<E> sources, Class<T> type) { List<T> items = new ArrayList<T>(); if (sources == null) { return items; } Iterator<E> iter = sources.iterator(); while (iter.hasNext()) { items.add(convert(iter.next(), type)); } return items; } /** * 通過無參數實例化目標對象和復制屬性,將POJO對象批量轉換成指定類型的對象 * * @param sources * List 原對象列表 * @param type * 目標類型 * @param ignoreProperties * 忽略的屬性列表 * @return List 目標類型對象列表 */ public static <T, E> List<T> convert(List<E> sources, Class<T> type, Class<?> editable, String[] ignoreProperties) { List<T> items = new ArrayList<T>(); if (sources == null) { return items; } Iterator<E> iter = sources.iterator(); while (iter.hasNext()) { items.add(convert(iter.next(), type, ignoreProperties)); } return items; } /** * 將Map的屬性設置到bean中 * * @param bean * @param properties * @throws IllegalAccessException * @throws InvocationTargetException */ public static void populate(Object bean, Map<String, ?> properties) throws IllegalAccessException, InvocationTargetException { org.apache.commons.beanutils.BeanUtils.populate(bean, properties); } /** * 將Bean轉化為Map對象 * * @param bean * @return * @throws IllegalAccessException * @throws InvocationTargetException * @throws NoSuchMethodException */ public static Map<?, ?> describe(Object bean) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { return org.apache.commons.beanutils.BeanUtils.describe(bean); } /** * 對bean的特定屬性賦值 * * @param bean * @param name * @param value * @throws IllegalAccessException * @throws InvocationTargetException */ public static void copyProperty(Object bean, String name, Object value) throws IllegalAccessException, InvocationTargetException { org.apache.commons.beanutils.BeanUtils.copyProperty(bean, name, value); } /** * 獲取bean的特定屬性 * * @param bean * @param name * @throws NoSuchMethodException * @throws IllegalAccessException * @throws InvocationTargetException */ public static String getProperty(Object bean, String name) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { return org.apache.commons.beanutils.BeanUtils.getProperty(bean, name); } /** * 基於Dozer轉換對象的類型. * * @param source * @param destinationClass * @return */ public static <T> T map(Object source, Class<T> destinationClass) { return dozer.map(source, destinationClass); } /** * 基於Dozer轉換List中對象的類型. * * @param sourceList * @param destinationClass * @return */ public static <T, E> List<T> map(List<E> sourceList, Class<T> destinationClass) { List<T> destinationList = new ArrayList<T>(); for (Object sourceObject : sourceList) { T destinationObject = dozer.map(sourceObject, destinationClass); destinationList.add(destinationObject); } return destinationList; } /** * 復制對象到一個已經存在的對象 * * @param source * 源對象 * @param target * 目標對象 */ public static void mapProperties(Object source, Object target) { dozer.map(source, target); } /** * 復制對象的指定屬性 * @param source * @param target * @param names * @throws BeansException */ public static void copyPropertiesByNames(Object source, Object target, String names) throws BeansException { Assert.notNull(source, "Source must not be null"); Assert.notNull(target, "Target must not be null"); Assert.hasText(names, "names must not be empty"); String[] keys = names.split(","); for (String name : keys) { name = name.trim(); PropertyDescriptor targetPd = getPropertyDescriptor( target.getClass(), name); PropertyDescriptor sourcePd = getPropertyDescriptor( source.getClass(), name); if (sourcePd != null && sourcePd.getReadMethod() != null && targetPd != null && targetPd.getWriteMethod() != null) { try { Method readMethod = sourcePd.getReadMethod(); if (!Modifier.isPublic(readMethod.getDeclaringClass() .getModifiers())) { readMethod.setAccessible(true); } Object value = readMethod.invoke(source); Method writeMethod = targetPd.getWriteMethod(); if (!Modifier.isPublic(writeMethod.getDeclaringClass() .getModifiers())) { writeMethod.setAccessible(true); } writeMethod.invoke(target, value); } catch (Throwable ex) { throw new FatalBeanException( "Could not copy properties from source to target", ex); } } } } /** * 將Bean的指定屬性集轉化為Map對象 * * @param bean * @param names * @return * @throws IllegalAccessException * @throws InvocationTargetException * @throws NoSuchMethodException */ public static Map<String, Object> describe(Object bean, String names) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { String[] attrs = StringUtils.split(names, ","); for (int i = 0; i < attrs.length; i++) { attrs[i] = attrs[i].trim(); } return describe(bean, attrs); } /** * 將Bean的指定屬性集轉化為Map對象 * * @param bean * @return * @throws IllegalAccessException * @throws InvocationTargetException * @throws NoSuchMethodException */ public static Map<String, Object> describe(Object bean, String[] names) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { Assert.notNull(bean, "Source must not be null"); Assert.notEmpty(names, "names must not be empty"); Map<String, Object> map = new HashMap<String, Object>(); for (String name : names) { map.put(name, getProperty(bean, name)); } return map; } }
三、測試類(這里簡單測試一兩個,自己使用時,自行測試)
public static void main(String [] args){ TblDept dept = new TblDept(); dept.setId(67); LocalDateTime localDateTime = LocalDateTime.now(); dept.setCreateTime(localDateTime); TblCompany company = new TblCompany(); company.setId(99); company.setRemark("備注"); // TblUserRecord convert = BeanUtils.convert(dept, TblUserRecord.class); TblUserRecord converts = BeanUtils.converts(dept, company, TblUserRecord.class); System.out.println(converts); }
四、測試結果
TblUserRecord{id=99, userName='null', userPassword='null', userType='null', tblRole=null, userGender='null', tblDept=null, userJob=null,
userStatus='null', officePhone='null', innerPhone='null', movePhone='null', email='null', isSendMsg='null', startDate=null, stopDate=null,
birthday=null, ipRule='null', userHiredate=null,
isSendWchat='null', remark='備注', createTime=2020-08-05T12:31:17.276, tblCompany=null, isDeptAdmin='null', lastLoginDate=null,
createPerson='null', createDate=null, token='null'}