ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

2021-09-22

2021-09-22 12:01:06  阅读:123  来源: 互联网

标签:target 22 getName 09 source declaredField 2021 null departmentid


昨天随便说一下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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有