2021-09-22
作者:互联网
昨天随便说一下pojo和vo和dto的关系给大家2个需求 昨天的博客的地址
https://mp.weixin.qq.com/s?__biz=MzA4MTAwMzA1Mw==&mid=2247484844&idx=1&sn=b950db1607efa078ccc41af61d885dc4&chksm=9f9ad2eea8ed5bf800d2a6d56eddebb33487f1db0741b6a71c0ea262db79480f7fbcb8119ebb&token=722122288&lang=zh_CN#rd
需求
假设是从A复制到B:
需求1:如果B中某字段有值(不为null),则该字段不复制;
也就是B中该字段没值时,才进行复制,适合于对B进行补充值的情况。
需求2:如果A中某字段没值(为null),则该字段不复制
也就是不要把null复制到B当中
先解决第一个需求
求1:如果B中某字段有值(不为null),则该字段不复制; 也就是B中该字段没值时,才进行复制,适合于对B进行补充值的情况。
解决方案
这里我使用的是自定义注解当自定义注解放在那个字段上面就不进行复制 重写这个复制的源码
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})//
// 1.CONSTRUCTOR:用于描述构造器
//2.FIELD:用于描述域
//3.LOCAL_VARIABLE:用于描述局部变量
//4.METHOD:用于描述方法//
// 6.PARAMETER:用于描述参数//
7.TYPE:用于描述类、接口(包括注解类型) 或enum声明
//ElementType.FIELD 只能用在字段上
@Documented
@Component
public @interface judge {
}
B
@Data
public class Department implements Serializable {
private Integer departmentid;
@judge
String departmentname;
private Integer managerid;
private String hh;
}
A
@Data
@NoArgsConstructor
public class DepartmentidDto {
private Integer departmentid;
private String departmentname;
private String hh;
}
main
public class YY {
public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
DepartmentidDto department=new DepartmentidDto();
department.setDepartmentid(1);
department.setHh("4444444");
department.setDepartmentname("2222222222222");
Department departmentid=new Department();
//
departmentid.setDepartmentname("3333333333333333333");
departmentid.setHh("12314");
// 前面是dto a 后面是pojo b
BeanUtilsVo.copyProperties(department,departmentid);
System.out.println(departmentid.toString());
}
}
可以看到a向b复制 字段departmentname的值在b是3333333333333333333 a的值是2222222在b上加上自定义注解
重写方法
public abstract class BeanUtilsVo {
/**使用的方法为copyProperties(Object source, Object target)**/
public static void copyProperties(Object source, Object target) throws BeansException {
//复制的 被复制的
copyProperties(source, target, (Class)null, (String[])null);
}
private static void copyProperties(Object source, Object target, @Nullable Class<?> editable, @Nullable String... ignoreProperties) throws BeansException {
Assert.notNull(source, "Source must not be null");
/**
//对象为空则抛出异常IllegalArgumentException
public static void notNull(@Nullable Object object, String message) {
if (object == null) {
throw new IllegalArgumentException(message);
}
}
**/
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(属性描述器)数组,getPropertyDescriptors具体内容看下方
PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);
List<String> ignoreList = ignoreProperties != null ? Arrays.asList(ignoreProperties) : null;
PropertyDescriptor[] var7 = targetPds;
int var8 = targetPds.length;
for(int var9 = 0; var9 < var8; ++var9) {
PropertyDescriptor targetPd = var7[var9];
//getWriteMethod中注释说明
//May return null if the property can't be written.
//也就是说对应的类中必须有set(写入)方法,否则返回空
Method writeMethod = targetPd.getWriteMethod();
System.out.println("=======================");
if (writeMethod != null && (ignoreList == null || !ignoreList.contains(targetPd.getName()))) {
//取出对应的属性并读取值
System.out.println( targetPd.getName());
// source.getClass().getDeclaredFields();
PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());
// System.out.println(sourcePd.getClass().getDeclaredFields().toString());
// boolean f=false;
// if (!Objects.isNull(sourcePd)){
// Field[] declaredFields = sourcePd.getClass().getDeclaredFields();
// System.out.println("ppppppppppppppppp"+declaredFields.length);
// if (declaredFields.length>0){
// for (Field declaredField : declaredFields) {
// judge fieldAnnotation =declaredField.getDeclaredAnnotation(judge.class);
// if (fieldAnnotation!=null){
// f=true;
// System.out.println("1111111111111");
// }
// }
// }
// }
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);
// Field[] declaredFields = source.getClass().getDeclaredFields();
System.out.println(value);
if (!Objects.isNull(value)){
if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
writeMethod.setAccessible(true);
}
Field[] declaredFields = target.getClass().getDeclaredFields();
int i=0;
for (Field declaredField : declaredFields) {
judge fieldAnnotation =declaredField.getDeclaredAnnotation(judge.class);
if (fieldAnnotation!=null){
if (targetPd.getName().equals(declaredField.getName())){
i++;
}
// System.out.println(declaredField.getName());
}
}
if (i==0){
//写入对应的值到目标类 关键
writeMethod.invoke(target, value);
}
}
// if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
// writeMethod.setAccessible(true);
// }
// Field[] declaredFields = target.getClass().getDeclaredFields();
// int i=0;
// for (Field declaredField : declaredFields) {
// judge fieldAnnotation =declaredField.getDeclaredAnnotation(judge.class);
// if (fieldAnnotation!=null){
// if (targetPd.getName().equals(declaredField.getName())){
// i++;
// }
System.out.println(declaredField.getName());
// }
//
// }
// if (i==0){
// //写入对应的值到目标类 关键
// writeMethod.invoke(target, value);
// }
//写入对应的值到目标类 关键
// writeMethod.invoke(target, value);
} catch (Throwable var15) {
throw new FatalBeanException("Could not copy property '" + targetPd.getName() + "' from source to target", var15);
}
}
}
}
}
}
}
核心是
Field[] declaredFields = target.getClass().getDeclaredFields();
int i=0;
for (Field declaredField : declaredFields) {
judge fieldAnnotation =declaredField.getDeclaredAnnotation(judge.class);
if (fieldAnnotation!=null){
if (targetPd.getName().equals(declaredField.getName())){
i++;
}
// System.out.println(declaredField.getName());
}
}
if (i==0){
//写入对应的值到目标类 关键
writeMethod.invoke(target, value);
}
执行看效果
看到里面的值还是没有改变 解决
需求2:如果A中某字段没值(为null),则该字段不复制 也就是不要把null复制到B当中
上面还是可以用
核心
Object value = readMethod.invoke(source);
// Field[] declaredFields = source.getClass().getDeclaredFields();
System.out.println(value);
看结果
看到
public class YY {
public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
DepartmentidDto department=new DepartmentidDto();
department.setDepartmentid(1);
department.setDepartmentname("2222222222222");
Department departmentid=new Department();
//
departmentid.setDepartmentname("3333333333333333333");
departmentid.setHh("12314");
// 前面是dto a 后面是pojo b
BeanUtilsVo.copyProperties(department,departmentid);
System.out.println(departmentid.toString());
}
}
日志
=======================
=======================
departmentid
1
=======================
departmentname
2222222222222
=======================
hh
null
=======================
managerid
Department(departmentid=1, departmentname=3333333333333333333, managerid=null, hh=12314)
希望可以给大家带来看源码的能力,和学习这个方法的源码是干什么的,怎么进行根据需求去改造这个源码,谢谢你的支持,这个问题,百度上也有,但是写的,看不懂,这个写的比较简单,希望给你带来学习的意义,去理解复制的原理
对这个需求有问题关注我微信公共号Java代码学习营地
标签:target,22,getName,09,source,declaredField,2021,null,departmentid 来源: https://blog.csdn.net/javazhudong/article/details/120412497