欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

java中使用cglib中的BeanCopier类进行bean的复制

程序员文章站 2022-03-27 12:56:09
复制java中的bean通常和前台交互时传输的bean和数据库中直接映射的bean不一致,或者使用线程ThreadLocal改变某些值,但java对象又是地址引用是会用到bean的复制直接给个简单的demo,这里只是用了我遇到的枚举类型的映射数据库中的对应类@Data@AllArgsConstructor@NoArgsConstructorpublic class Student { private String name; private StudentType studen...

复制java中的bean

通常和前台交互时传输的bean和数据库中直接映射的bean不一致,或者使用线程ThreadLocal改变某些值,但java对象又是地址引用时会用到bean的复制

直接给个简单的demo,这里只是用了我遇到的枚举类型的映射
数据库中的对应类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    private String name;
    private StudentType studentType;
}
StudentType的枚举类
public enum  StudentType {
    MAN(0,"男"),
    WOMAN(1,"女");
    private int code;
    private String value;
    StudentType(int code, String value) {
        this.code = code;
        this.value = value;
    }
    public int getCode() {
        return code;
    }
    public String getValue() {
        return value;
    }
    public static StudentType fromCode(int code){
        for (StudentType value : StudentType.values()) {
            if (value.getCode()==code){
                return value;
            }
        }
        return null;
    };
    @Override
    public String toString() {
        return "StudentType{" +
                "value='" + value + '\'' +
                '}';
    }
}
要传输出去的类
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class StudentOutPut {
    private String name;
    private Integer studentType;
}
最后就是复制bean的代码块了,主要介绍转换器中三个参数
这里我写在了一个controller中触发复制,但并不是一定要在web项目中才能使用,引入了对应的包即可
@RequestMapping(value = "/helloWorld",produces="text/html;charset=UTF-8")
    @ResponseBody
    public String helloWorld(HttpServletRequest request){
        Student student = new Student("测试用", StudentType.MAN);

        Converter converter = new Converter() {
            @Override
            public Object convert(Object o, Class aClass, Object o1) {
       //o要复制的对象的对应的属性的值,比如此次复制到的Student属性是 name,那么这个 o的值就是 "测试用" 也就是我上面创建的对应值
      // aClass复制到的目标对象名称相同对应的属性对象类型,比如复制到name时,aClass就是String
      // o1目标对象的设置值方法名,比如复制name属性时,o1就是setName
      //剩下的就是根据这三个参数自己进行转换了,方法的返回值将会填入目标对象对应的属性值。
      //比如我这里特殊处理了StudentType属性字段         
                try {
                    if (o instanceof Enum){ //如果此次的属性是枚举类型
                        Method method = ((Enum) o).getDeclaringClass().getMethod("getCode"); //我的枚举定义了getCode()方法
                        Object invoke = method.invoke(o);//通过反射执行getCode()方法
                        return invoke;//返回执行完的getCode()方法返回的值,这里就是StudentType.MAN对应的code值。
                    }
                    return o; //这里我只用了俩个属性,name字段String类型直接返回即可
                } catch (Exception e) {
                    throw new IllegalStateException("复制bean失败");
                }
            }
        };
        StudentOutPut studentOutPut = new StudentOutPut();
        BeanCopier beanCopier = BeanCopier.create(Student.class,StudentOutPut.class, true);
        beanCopier.copy(student,studentOutPut,converter);
        request.getSession().setAttribute("user",studentOutPut);
        System.out.println(studentOutPut);
页面请求后,打印结果
StudentOutPut(name=测试用, studentType=0)
成功将 Student中StudentType枚举类型映射成了 StudentOuput中的 studentType中的Integer类型,值就是对应枚举类的code值

提示:要复制的bean和目标bean对应的字段属性名一点更要一致,否则将不会走进传入的自定义 Converter对象

比如我这里Student中 private StudentType studentType;

和StudentOutPut中的private Integer studentType;

虽然属性类型不一样,但是属性名一定要保持一致

本文地址:https://blog.csdn.net/weixin_46415189/article/details/110481114

相关标签: java spring