V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zhangqian99
V2EX  ›  Java

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

  •  
  •   zhangqian99 · 2023-11-14 08:49:49 +08:00 · 2142 次点击
    这是一个创建于 385 天前的主题,其中的信息可能已经有所发展或是发生改变。

    例如:

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

    搞 copy 都是脱裤子放屁💨,有那时间早 set 好了。
    theniupa
        9
    theniupa  
       2023-11-14 09:41:02 +08:00
    有那时间早 set 好了+1
    SirYuxuan
        10
    SirYuxuan  
       2023-11-14 09:43:56 +08:00   ❤️ 1
    ```
    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
        11
    Plutooo  
       2023-11-14 09:45:32 +08:00
    重复造的轮子对比 mapstruct 有什么优势呢
    SirYuxuan
        12
    SirYuxuan  
       2023-11-14 09:47:56 +08:00
    不太明白为啥一点技术的氛围都没有呢,都会说在造轮子,up 说不定只是想学习一下实现的思路呢,技术无罪
    zhangqian99
        13
    zhangqian99  
    OP
       2023-11-14 09:51:28 +08:00
    @Plutooo 这个是外包项目,在甲方虚拟机离线环境下编程,没有办法
    yazinnnn0
        14
    yazinnnn0  
       2023-11-14 10:32:48 +08:00
    https://github.com/mapstruct/mapstruct

    从最早的 commit 看, 抄过来用用
    yazinnnn0
        15
    yazinnnn0  
       2023-11-14 10:35:08 +08:00
    另外, 离线开发都没有给 mvn 仓库镜像吗? 难道要手搓 framework?
    Navee
        16
    Navee  
       2023-11-14 10:45:41 +08:00   ❤️ 1
    '''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
        17
    chendy  
       2023-11-14 10:46:50 +08:00
    @zhangqian99 #3 那你好像已经把答案说出来了…
    注解的方式不一定最优,因为需要处理的逻辑量更大,如果要转换的东西本来就不多,那直接反射更方便
    其实还有一些办法比如生成 get set 代码之类的,差别其实不大
    另外如果是甲方离线环境…如果有入口的话直接把 mapstruct 或者其他库的 jar 包传进去配到依赖里也行
    lyxeno
        18
    lyxeno  
       2023-11-14 11:29:46 +08:00
    get set 好了,方便 IDE 重构和分析。
    gabon
        19
    gabon  
       2023-11-14 13:17:58 +08:00 via iPhone
    不要用反射,离线环境考虑把 mapstruct 的 jar 包打到 classpath 里
    xuanbg
        20
    xuanbg  
       2023-11-14 13:25:31 +08:00
    通用的话就是加注解,然后自己写个静态方法调用就成。
    jorneyr
        21
    jorneyr  
       2023-11-14 13:49:07 +08:00
    自己实现一个工具,不就是不依赖其他库了么。
    allecnm
        22
    allecnm  
       2023-11-14 14:33:34 +08:00
    get set 就行了呗
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1082 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 19:14 · PVG 03:14 · LAX 11:14 · JFK 14:14
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.