zhangqian99
V2EX  ›  Java

在 bean 之间复制具有不同名称的属性,不使用其他依赖库的情况下

  •  
  •   zhangqian99 · Nov 14, 2023 · 5452 views
    This topic created in 1089 days ago, the information mentioned may be changed or developed.

    例如:

    class ClassA{
        private String name;
        private Integer age;
        private List<C> cList;
        Private D d;
        省略 setter,getter
    } 
    
    class ClassB{
        private String differentName;
        private Integer differentAge;
        private List<C> differCList;
        private D differD;
        省略 setter,getter
    }
    
    22 replies  •  2023-11-14 14:33:34 +08:00
    chendy
    chendy
    Nov 14, 2023❤️3
    1
    楼主这是提了个问题么?
    不依赖其他库,不考虑不同类型,最简单实现就是弄个 map 保存字段映射关系,然后处理
    然后伴随着业务的发展,不同类型需要处理,部分字段需要忽略,每次反射拿字段拿方法效率不行要缓存…最后就自己实现了一个 copy 库
    zero47
    zero47
    Nov 14, 2023
    2
    让 A 给 B 做构造入参
    zhangqian99
    zhangqian99
    OP
    Nov 14, 2023
    3
    @chendy 想写一个工具类,使用注解的方式,有没有好的思路
    aosan926
    aosan926
    Nov 14, 2023
    4
    参考序列化与反序列化?
    jsboy
    jsboy
    Nov 14, 2023
    5
    java 的话,直接 mapstruct 吧,别重复造轮子了。
    sumarker
    sumarker
    Nov 14, 2023❤️1
    6
    不管是怎样映射关系总是需要维护的:
    1.通过自定义注解,写在属性上,然后反射解析到对应的类属性上
    2.搞一个中间类处理
    3. 把映射关系,存在 xml 或者数据库里
    dc2002007
    dc2002007
    Nov 14, 2023
    7
    搞 java 的总是喜欢把一些很简单的东西提出来讨论
    looo
    looo
    Nov 14, 2023
    8
    写这代码,还不如老老实实去手动 get set 装个插件一件生成 set 方法。

    搞 copy 都是脱裤子放屁💨,有那时间早 set 好了。
    theniupa
    theniupa
    Nov 14, 2023
    9
    有那时间早 set 好了+1
    SirYuxuan
    SirYuxuan
    Nov 14, 2023❤️1
    10
    ```
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;

    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface PropertyMapping {
    String value();
    }

    ```
    ```
    import java.lang.reflect.Field;

    public class BeanMapper {

    public static void copyProperties(Object source, Object destination) {
    Class<?> sourceClass = source.getClass();
    Class<?> destClass = destination.getClass();

    Field[] sourceFields = sourceClass.getDeclaredFields();

    for (Field sourceField : sourceFields) {
    if (sourceField.isAnnotationPresent(PropertyMapping.class)) {
    String sourceFieldName = sourceField.getName();
    String destinationFieldName = sourceField.getAnnotation(PropertyMapping.class).value();

    try {
    Field destField = destClass.getDeclaredField(destinationFieldName);
    sourceField.setAccessible(true);
    destField.setAccessible(true);

    Object value = sourceField.get(source);
    destField.set(destination, value);
    } catch (NoSuchFieldException | IllegalAccessException e) {
    e.printStackTrace(); // 处理异常,可以根据实际情况进行调整
    }
    }
    }
    }
    }

    ```
    Plutooo
    Plutooo
    Nov 14, 2023
    11
    重复造的轮子对比 mapstruct 有什么优势呢
    SirYuxuan
    SirYuxuan
    Nov 14, 2023
    12
    不太明白为啥一点技术的氛围都没有呢,都会说在造轮子,up 说不定只是想学习一下实现的思路呢,技术无罪
    zhangqian99
    zhangqian99
    OP
    Nov 14, 2023
    13
    @Plutooo 这个是外包项目,在甲方虚拟机离线环境下编程,没有办法
    yazinnnn0
    yazinnnn0
    Nov 14, 2023
    14
    https://github.com/mapstruct/mapstruct

    从最早的 commit 看, 抄过来用用
    yazinnnn0
    yazinnnn0
    Nov 14, 2023
    15
    另外, 离线开发都没有给 mvn 仓库镜像吗? 难道要手搓 framework?
    Navee
    Navee
    Nov 14, 2023❤️1
    16
    '''java
    class ClassA{
    private String name;
    private Integer age;
    private List<C> cList;
    Private D d;

    public ClassA(ClassB classB){
    ClassA a = new ClassA();
    //映射逻辑
    return a;
    }
    省略 setter,getter
    }

    class ClassB{
    private String differentName;
    private Integer differentAge;
    private List<C> differCList;
    private D differD;

    public ClassB(ClassA classA){
    ClassB b = new ClassB();
    //映射逻辑
    return b;
    }

    省略 setter,getter
    }
    '''
    chendy
    chendy
    Nov 14, 2023
    17
    @zhangqian99 #3 那你好像已经把答案说出来了…
    注解的方式不一定最优,因为需要处理的逻辑量更大,如果要转换的东西本来就不多,那直接反射更方便
    其实还有一些办法比如生成 get set 代码之类的,差别其实不大
    另外如果是甲方离线环境…如果有入口的话直接把 mapstruct 或者其他库的 jar 包传进去配到依赖里也行
    lyxeno
    lyxeno
    Nov 14, 2023
    18
    get set 好了,方便 IDE 重构和分析。
    gabon
    gabon
    Nov 14, 2023 via iPhone
    19
    不要用反射,离线环境考虑把 mapstruct 的 jar 包打到 classpath 里
    xuanbg
    xuanbg
    Nov 14, 2023
    20
    通用的话就是加注解,然后自己写个静态方法调用就成。
    jorneyr
    jorneyr
    Nov 14, 2023
    21
    自己实现一个工具,不就是不依赖其他库了么。
    allecnm
    allecnm
    Nov 14, 2023
    22
    get set 就行了呗
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   723 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 49ms · UTC 19:45 · PVG 03:45 · LAX 11:45 · JFK 14:45
    ♥ Do have faith in what you're doing.