|
|
|
@ -0,0 +1,185 @@
|
|
|
|
|
package com.ibeetl.admin.core.util;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import com.ibeetl.admin.core.entity.BaseEntity;
|
|
|
|
|
import org.springframework.beans.BeanUtils;
|
|
|
|
|
import org.springframework.util.ObjectUtils;
|
|
|
|
|
import org.springframework.util.StopWatch;
|
|
|
|
|
|
|
|
|
|
import java.lang.reflect.Field;
|
|
|
|
|
import java.lang.reflect.InvocationTargetException;
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
import java.util.concurrent.CopyOnWriteArrayList;
|
|
|
|
|
import java.util.function.Supplier;
|
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
|
|
import static org.apache.commons.beanutils.MethodUtils.invokeMethod;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Bean拷贝工具类 扩展
|
|
|
|
|
*
|
|
|
|
|
* @author mlx
|
|
|
|
|
* @date 2022/5/29
|
|
|
|
|
* @modified
|
|
|
|
|
*/
|
|
|
|
|
public class BeanCopyUtil extends BeanUtils {
|
|
|
|
|
|
|
|
|
|
public interface ThConsumer<T, U, O> {
|
|
|
|
|
|
|
|
|
|
void accept(T t, U u, O o);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 集合数据的拷贝
|
|
|
|
|
* @param sources: 数据源类
|
|
|
|
|
* @param target: 目标类::new(eg: UserVO::new)
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public static <S, T> List<T> copyListProperties(List<S> sources, Supplier<T> target) {
|
|
|
|
|
return copyListProperties(sources, target, ArrayList::new,null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 集合数据的拷贝
|
|
|
|
|
* @param sources: 数据源类
|
|
|
|
|
* @param target: 目标类::new(eg: UserVO::new)
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public static <S, T> List<T> copyListProperties(List<S> sources, Supplier<T> target, BeanCopyUtilCallBack<S, T> callBack) {
|
|
|
|
|
return copyListProperties(sources, target, ArrayList::new,callBack);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 带回调函数的集合数据的拷贝(可自定义字段拷贝规则)
|
|
|
|
|
* @param sources: 数据源类
|
|
|
|
|
* @param target: 目标类::new(eg: UserVO::new)
|
|
|
|
|
* @param callBack: 回调函数
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public static <S, T> List<T> copyListProperties(List<S> sources, Supplier<T> target, Supplier<List<T>> supplier, BeanCopyUtilCallBack<S, T> callBack) {
|
|
|
|
|
List<T> list = supplier.get();
|
|
|
|
|
for (S source : sources) {
|
|
|
|
|
T t = target.get();
|
|
|
|
|
copyProperties(source, t);
|
|
|
|
|
list.add(t);
|
|
|
|
|
if (callBack != null) {
|
|
|
|
|
// 回调
|
|
|
|
|
callBack.callBack(source, t);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return list;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 单线程处理 BaseEntity对象转Map
|
|
|
|
|
* @param target
|
|
|
|
|
* @param <T>
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public static <T extends BaseEntity> List<Map<String, Object>> BaseEntity2Map(List<T> target) {
|
|
|
|
|
StopWatch sw = new StopWatch();
|
|
|
|
|
sw.start();
|
|
|
|
|
List<Map<String, Object>> res = new ArrayList<>();
|
|
|
|
|
if (ObjectUtils.isEmpty(target)) {
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
Field[] fields = target.get(0).getClass().getDeclaredFields();
|
|
|
|
|
for (T baseEntity : target) {
|
|
|
|
|
for (Field declaredField : fields) {
|
|
|
|
|
baseEntity.set(getFiledName(declaredField), getFieldValue(baseEntity, "get" + getFirstUpperCaseFiledName(declaredField)));
|
|
|
|
|
}
|
|
|
|
|
res.add(baseEntity.getTails());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sw.stop();
|
|
|
|
|
System.out.println("BaseEntity2MapWithParallel:" + sw.getTotalTimeSeconds() + "秒, 集合长度:" + res.size());
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 并行处理 BaseEntity对象转Map
|
|
|
|
|
* @param target
|
|
|
|
|
* @param <T>
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public static <T extends BaseEntity> List<Map<String, Object>> BaseEntity2MapWithParallel(List<T> target) {
|
|
|
|
|
return BaseEntity2MapWithParallel(target, (k, v, o) -> {});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 并行处理 BaseEntity对象转Map
|
|
|
|
|
* @param target
|
|
|
|
|
* @param <T>
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public static <T extends BaseEntity> List<Map<String, Object>> BaseEntity2MapWithParallel(List<T> target, ThConsumer<String, Object, T> consumer) {
|
|
|
|
|
StopWatch sw = new StopWatch();
|
|
|
|
|
sw.start();
|
|
|
|
|
List<Map<String, Object>> res = new ArrayList<>();
|
|
|
|
|
if (ObjectUtils.isEmpty(target)) {
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
final Field[] fields = target.get(0).getClass().getDeclaredFields();
|
|
|
|
|
|
|
|
|
|
List<Map<String, Object>> collect = target.parallelStream().map(baseEntity -> {
|
|
|
|
|
for (Field declaredField : fields) {
|
|
|
|
|
String filedName = getFiledName(declaredField);
|
|
|
|
|
String fieldValue = getFieldValue(baseEntity, "get" + getFirstUpperCaseFiledName(declaredField));
|
|
|
|
|
baseEntity.set(filedName, fieldValue);
|
|
|
|
|
}
|
|
|
|
|
baseEntity.getTails().forEach((k,v) -> consumer.accept(k,v, baseEntity));
|
|
|
|
|
return baseEntity.getTails();
|
|
|
|
|
}).collect(Collectors.toCollection(CopyOnWriteArrayList::new));
|
|
|
|
|
|
|
|
|
|
sw.stop();
|
|
|
|
|
System.out.println("BaseEntity2MapWithParallel:" + sw.getTotalTimeSeconds() + "秒, 集合长度:" + collect.size());
|
|
|
|
|
return collect;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
|
|
* 获取对象的属性和属性值
|
|
|
|
|
*
|
|
|
|
|
* @author ghj
|
|
|
|
|
* @return
|
|
|
|
|
* @throws Throwable
|
|
|
|
|
*/
|
|
|
|
|
public static String getFieldValue(Object owner, String fieldName) {
|
|
|
|
|
try {
|
|
|
|
|
if(invokeMethod(owner, fieldName, null)!=null){
|
|
|
|
|
return invokeMethod(owner, fieldName, null).toString();
|
|
|
|
|
}else{
|
|
|
|
|
return "null";
|
|
|
|
|
}
|
|
|
|
|
} catch (NoSuchMethodException e) {
|
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
|
} catch (IllegalAccessException e) {
|
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
|
} catch (InvocationTargetException e) {
|
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取属性的名称,首字母大写
|
|
|
|
|
* @param f
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public static String getFirstUpperCaseFiledName(Field f) {
|
|
|
|
|
String str = f.toString().substring(f.toString().lastIndexOf('.') + 1);
|
|
|
|
|
return str.substring(0, 1).toUpperCase() + str.replaceFirst("\\w", "");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取属性的名称
|
|
|
|
|
* @param f
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public static String getFiledName(Field f) {
|
|
|
|
|
return f.toString().substring(f.toString().lastIndexOf('.') + 1);
|
|
|
|
|
}
|
|
|
|
|
}
|