背景
开发’复制’功能时,清除’create_time’,'create_id’等无用信息,可能会产生如下代码:
obj.setCreateTime(null);
obj.setCreateId(null);
.....大量setNull操作....
新增实体属性注解@CopySetEmpty
- 使用范围: 实体类的属性字段 (支持VO类)
- 原理: 反射判断是属性注解是否存在,收集需要处理的属性名,使用BeanUtil.copyProperties处理
- 工具类源码:
/**
* 判断是否需要忽略当前属性
*
* @param field 反射字段
* @return true 忽略
*/
private static boolean ignoreCurrent(Field field) {
//基本类型,直接跳过 (属性命名不规范,会导致报错)
if (field.getType().isPrimitive()) {
return true;
}
//无'清空标记'的字段直接跳过
CopySetEmpty annotation = field.getAnnotation(CopySetEmpty.class);
return ObjectUtil.isNull(annotation);
}
/**
* 将实体类上带有 @CopySetEmpty注解的属性清空支持vo类
* @param t javabean
*/
public static <T> T setEmptyValueByAnnotation(T t) {
if (ObjectUtil.isNull(t)) {
return null;
}
T newObj = t;
try {
Field[] allFields = new Field[]{};
List<String> fieldNames = new ArrayList<>();
Class<?> clazz = t.getClass();
Field[] declaredFields;
while (clazz != null) {
// 获取字节码对象的属性对象数组
declaredFields = clazz.getDeclaredFields();
allFields = ArrayUtil.append(allFields, declaredFields);
// 获得父类的字节码对象
clazz = clazz.getSuperclass();
}
for (Field field : allFields) {
// 判断是否需要忽略当前属性
if (ignoreCurrent(field)) {
continue;
}
fieldNames.add(field.getName());
}
newObj = (T) clazz.newInstance();
BeanUtil.copyProperties(t, newObj, ArrayUtil.toArray(fieldNames, String.class));
} catch (Exception e) {
log.error("复制操作工具类:反射获取实例异常");
log.error(ExceptionUtil.stacktraceToString(e));
}
return newObj;
}
- 返回对象为处理后的对象
- 注意: 需要主动接收返回值,如下使用示例
使用示例
/**
* 复制单条记录
*
* @param id 主键
* @return R
*/
@Override
public R copy(String id) {
//根据id获取db记录
OmsOrder omsOrder = getById(id);
//将实体类上带有 @CopySetEmpty注解的属性清空
omsOrder = CopySetEmptyUtil.setEmptyValueByAnnotation(omsOrder);
return new R<>(omsOrder);
}