分享一个 Javabean 拷贝工具 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
KeroZhai
V2EX    程序员

分享一个 Javabean 拷贝工具

  •  
  •   KeroZhai
    kerozhai 2020-12-06 16:29:13 +08:00 via iPhone 3454 次点击
    这是一个创建于 1850 天前的主题,其中的信息可能已经有所发展或是发生改变。

    由于项目中需要根据条件返回 PO 中不同的字段,但又不想定义多个 VO 类,于是我就从自身需求出发,完成了下面这个 Javabean 拷贝工具。

    仓库地址在这里,希望能给大家带来一点点微小的帮助,也希望大家可以提提建议,甚至帮助改进,大佬们请轻喷。

    第 1 条附言    2020-12-06 17:17:10 +08:00
    需要说明一下,说实话对我来说,现阶段我更看重的是功能易用性,所以暂时可能不太适合看重性能的兄弟萌...但是我也希望二者兼得,后面会持续改进的。
    第 2 条附言    2020-12-06 17:32:48 +08:00
    可能 README 中描述的还不是特别详细,这个工具应该算是开箱即用的,因为是深拷贝,所以关联的其他 Javabean 及其数组或集合也都会一并拷贝,不需要额外配置。
    第 3 条附言    2020-12-07 18:58:17 +08:00

    大家评论里提到的其他优秀的拷贝工具我大概都了解了下,感觉自己确实孤陋寡闻了...不过如果只考虑功能而不考虑具体实现、性能等,我觉得我这个工具还是有它的可取之处和用武之地的,并且相对来说应该是简单易用的,后续的目标也是保持简单的上层 API 不变,持续优化底层实现,提高性能。

    突然想起来项目里写的几个粗略的单元测试刚好可以作为简单的示例,从而直观地展示下几个功能和用法,有兴趣的小伙伴可以抽空瞄两眼:

    14 条回复    2020-12-07 14:39:58 +08:00
    TheCure
        1
    TheCure  
       2020-12-06 16:53:28 +08:00   1
    KeroZhai
        2
    KeroZhai  
    OP
       2020-12-06 17:05:04 +08:00 via iPhone
    @callofmx 感谢回复,大概看了下,它要解决的问题应该和我是一致的,不过个人觉得可能我的用法会更简单灵活一点,特别是对字段的条件拷贝这方面,不需要定义额外的 Mapper 。
    tcfenix
        3
    tcfenix  
       2020-12-06 17:16:01 +08:00
    @KeroZhai 记得之前使用最广的是 cglib 的 bean copier, 有很多使用了的项目,时间跨度都很广, 是经得住考验工具

    扫了一下,你的大致逻辑跟他比较接近,都是反射实现加上缓存 converter, 不知道具体的实现上有没有啥区别?
    KeroZhai
        4
    KeroZhai  
    OP
       2020-12-06 17:27:45 +08:00 via iPhone
    @tcfenix 谢谢您的回复,Beancopier 我了解的不是很多,只知道它的性能可媲美直接使用 getters/setters,另外好像是浅拷贝?因为我的实现中基本类型、Date 以及 Collection 都是直接支持的,并且是递归深拷贝,一般情况下是不需要 Converter 的,只有想实现一些特殊需求的时候可以配置,例如 README 中举例的时间戳转 Date 对象。
    beitayongguo
        5
    beitayongguo  
       2020-12-06 17:43:22 +08:00
    orika 用着还挺好的,也是字节码框架实现的
    KeroZhai
        6
    KeroZhai  
    OP
       2020-12-06 17:58:04 +08:00 via iPhone
    @beitayongguo 谢谢推荐,不过感觉需要额外配置 Mapper 的话稍微有点繁琐,当然如果要是比性能我这个就完败了…不管怎样,希望能点个 Star 支持下哈哈。
    xuanbg
        7
    xuanbg  
       2020-12-06 18:57:48 +08:00
    序列化+反序列化就完了,要什么自行车
    KeroZhai
        8
    KeroZhai  
    OP
       2020-12-06 19:13:08 +08:00 via iPhone
    @xuanbg 是,主要是有条件拷贝不同字段的需求,而且两边字段类型名称都可能不同,比如 UserPo -> UserDTO,UserPO 内又有 List<RolePO>,而 UserDTO 内对应的是 List<RoleDTO> 这样。
    paragon
        9
    paragon  
       2020-12-06 22:30:57 +08:00
    其实 spring beanutils 足够应付大多数这种场景了
    xuanbg
        10
    xuanbg  
       2020-12-07 08:27:16 +08:00
    @KeroZhai 那么字段怎么对应呢?搞个 map 传进去么?有写这个 map 的美国功夫,我 new 一个目标对象出来手动 set 一下就完了。
    KeroZhai
        11
    KeroZhai  
    OP
       2020-12-07 08:57:27 +08:00 via iPhone
    @xuanbg 默认根据字段名来对应的,一般使用上不需要配置啥,只是需要声明一些条件,并在拷贝时指定这些条件,来决定这次拷贝要忽略哪些字段或是采取哪种策略来忽略它们。如果你使用的是 JPA 的话,应该知道关联关系可能嵌套好几层,特别是关联集合,如果全部手动 set 可能不太现实。当然如果没有这个需要的话,确实价值意义不大…
    KeroZhai
        12
    KeroZhai  
    OP
       2020-12-07 09:05:09 +08:00 via iPhone
    @paragon 不过它也是浅拷贝吧,像是关联查询出来“用户-角色-权限”三种实体类,再转为 VO 的时候应该就没办法了。不过其实个人觉得我这个重点不是递归深拷贝,主要是按条件拷贝以及指定如何忽略 null 和空值两个功能比较方便,对我来说很有用...
    syozzz
        13
    syozzz  
       2020-12-07 13:03:39 +08:00
    dozer?
    KeroZhai
        14
    KeroZhai  
    OP
       2020-12-07 14:39:58 +08:00 via iPhone
    @syozzz 感谢回复,说实话一下子知道了好多拷贝工具…了解了一下确实挺强大的,不过正如我前面提到的,我觉得使用 XML 去配置映射有点麻烦,更倾向于使用注解。还有就是希望能尽量复用一个类,根据一定的条件选择要拷贝哪些字段,这个可能是对我来说这个工具最主要想解决的问题吧。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1181 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 32ms UTC 17:48 PVG 01:48 LAX 09:48 JFK 12:48
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86