SpringBoot 如何进行对象复制

首先我们看看为什么需要对象复制?

为什么需要对象复制

SpringBoot 如何进行对象复制

如上,是我们平时开发中最常见的三层MVC架构模型,编辑操作时Controller层接收到前端传来的DTO对象,在Service层需要将 DTO转换成 DO,然后在数据库中保存。查询操作时Service层查询到DO对象后需要将 DO对象转换成 VO对象,然后通过Controller层返回给前端进行渲染。

这中间会涉及到大量的对象转换,很明显我们不能直接使用 getter/setter复制对象属性,这看上去太low了。想象一下你业务逻辑中充斥着大量的 getter&setter,代码评审时老鸟们会如何笑话你?

SpringBoot 如何进行对象复制

所以我们必须要找一个第三方工具来帮我们实现对象转换。

看到这里有同学可能会问,为什么不能前后端都统一使用DO对象呢?这样就不存在对象转换呀?设想一下如果我们不想定义 DTO 和 VO,直接将 DO 用到数据访问层、服务层、控制层和外部访问接口上。此时该表删除或则修改一个字段,DO 必须同步修改,这种修改将会影响到各层,这并不符合高内聚低耦合的原则。通过定义不同的 DTO 可以控制对不同系统暴露不同的属性,通过属性映射还可以实现具体的字段名称的隐藏。不同业务使用不同的模型,当一个业务发生变更需要修改字段时,不需要考虑对其它业务的影响,如果使用同一个对象则可能因为 “不敢乱改” 而产生很多不优雅的兼容性行为。

对象复制工具类推荐

对象复制的类库工具有很多,除了常见的Apache的 BeanUtils,Spring的 BeanUtilsCglib BeanCopier,还有重量级组件 MapStructOrikaDozerModelMapper等。

如果没有特殊要求,这些工具类都可以直接使用,除了Apache的BeanUtils。原因在于Apache BeanUtils底层源码为了追求完美,加了过多的包装,使用了很多反射,做了很多校验,所以导致性能较差,并在阿里巴巴开发手册上强制规定避免使用 Apache BeanUtils。

SpringBoot 如何进行对象复制

至于剩下的重量级组件,综合考虑其性能还有使用的易用性,我这里更推荐使用 Orika。Orika底层采用了javassist类库生成Bean映射的字节码,之后直接加载执行生成的字节码文件,在速度上比使用反射进行赋值会快很多。

国外大神 baeldung 已经对常见的组件性能进行过详细测试,大家可以通过 https://www.baeldung.com/java-performance-mapping-frameworks 查看。

Orika基本使用

要使用Orika很简单,只需要简单四步:

  1. 引入依赖

java;gutter:true; ma.glasnost.orika orika-core 1.5.4</p> <pre><code> 1. 构造一个MapperFactory ;gutter:true;
MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();

  1. 注册字段映射

java;gutter:true; mapperFactory.classMap(SourceClass.class, TargetClass.class) .field("firstName", "givenName") .field("lastName", "sirName") .byDefault() .register();</p> <pre><code> 当字段名在两个实体不一致时可以通过 .field()方法进行映射,如果字段名都一样则可省略, ()方法用于注册名称相同的属性,如果不希望某个字段参与映射,可以使用 方法。 经过上面四步我们就完成了SourceClass到TargetClass的转换。至于Orika的其他使用方法大家可以参考 ://orika-mapper.github.io/orika-docs/index.html看到这里,肯定有粉丝会说:你这推荐的啥玩意呀,这个Orika使用也不简单呀,每次都要这先创建 ,建立字段映射关系,才能进行映射转换。 别急,我这里给你准备了一个工具类 ,你可以通过文末github仓库获取。 它提供了五个公共方法: ![SpringBoot 如何进行对象复制](https://johngo-pic.oss-cn-beijing.aliyuncs.com/articles/20230526/7f3f77c1557d6251edce9603a558f1a1.png) 分别对应: 1. 字段一致实体转换 2. 字段不一致实体转换(需要字段映射) 3. 字段一致集合转换 4. 字段不一致集合转换(需要字段映射) 5. 字段属性转换注册 接下来我们通过单元测试案例重点介绍此工具类的使用。 ## Orika工具类使用文档 先准备两个基础实体类,Student,Teacher。 ;gutter:true;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private String id;
private String name;
private String email;
}

此时由于对字段做了映射,可以将email映射到emailAddress。注意这里的refMap中key放置的是源实体的属性,而value放置的是目标实体的属性,不要弄反了。

小结

在MVC架构中肯定少不了需要用到对象复制,属性转换的功能,借用Orika组件,可以很简单实现这些功能。本文在Orika的基础上封装了工具类,进一步简化了Orika的操作,希望对各位有所帮助。

Original: https://www.cnblogs.com/aishangJava/p/15333476.html
Author: 工程师搁浅
Title: SpringBoot 如何进行对象复制

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/538979/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • requested upstream branch ‘origin/master’ does not exist

    本地的commit 本地仓库有文件,远程仓库也有文件,正确姿势: 1,git remote add origin 远程仓库地址 2,git pull origin master &…

    Java 2023年6月13日
    076
  • html图片上传并预览笔记

    一、图片上传,原图无压缩 1、用到的js和css(只为美规,可以不用):jasny-bootstrap.css、jasny-bootstrap.js 2、、html代码 3、后台接…

    Java 2023年6月5日
    0108
  • Sentinel

    方法级别降级 * 类级别降级 慢调用比例 异常比例 * 异常数 QPS-直接-快速失败 来源应用 QPS-直接-Warm Up QPS-直接-排队等待 QPS-关联-快速失败 QP…

    Java 2023年6月8日
    077
  • 程序员最容易读错的单词,听到status我炸了

    最近在跟同事讨论问题的时候,他突然对我说。。。 这个 死太丢死不太对,需要改一下。。。 我当时应该是愣住了,然后想了一下,你说的是 status 吗??? 看着他疑惑不解的眼神,我…

    Java 2023年6月13日
    072
  • RocketMQ基本原理

    基础概念 RocketMQ主要由Producer、Broker、Consumer三部分组成,其中Producer负责生产消息,Consumer负责消费消息,Broker负责存储消息…

    Java 2023年6月6日
    079
  • 阅读笔记三

    读《梦断代码》有一段时间了,此书从卡普尔的chandler项目深刻剖析了”软件难做”的几大原因,每章都使人回味无穷。合上书本,我作为一名计算机系的学生,感到…

    Java 2023年6月7日
    066
  • PostgreSQL远程访问设置

    数据库版本:9.3.23(Windows xp系统) 步骤: 1、需要修改数据库安装目录下的pg_hba.conf文件 修改成: 2、并使用psql执行pg_ctl reload重…

    Java 2023年6月5日
    076
  • 【转】Java之WeakReference与SoftReference使用讲解

    Java 2 平台引入了 java.lang.ref 包,其中包括的类可以让您引用对象,而不将它们留在内存中。这些类还提供了与垃圾收集器(garbage collector)之间有…

    Java 2023年5月29日
    076
  • 简述一条查询语句的执行过程

    大体来说,MySQL 可以分为 Server 层和 存储引擎层两部分。 Server 层包括连接器、查询缓存、分析器、优化器、执行器等 存储引擎层负责数据的存储和提取。 一个查询语…

    Java 2023年6月5日
    082
  • 【JavaWeb-Ajax】笔记汇总 — 全局刷新和局部刷新;ajax 中使用 XMLHttpRequest 对象(四步);json 的使用

    1、全局刷新和局部刷新: 1)全局刷新:整个浏览器被新的数据覆盖,在网络中传输大量的数据(浏览器需要加载,渲染页面)。 2)局部刷新:在浏览器的内部,发起请求,获取数据,改变页面中…

    Java 2023年6月8日
    099
  • 现代医院信息化建设策略与实践

    概要: 优化医院服务流程,改善患者就医体验。 支撑门诊医疗服务,提高门诊诊疗水平。 规范急诊业务管理,强化急救治疗能力。 提高医院医疗效率,保障临床医疗质量。 规范护理服务流程,提…

    Java 2023年5月29日
    095
  • javaEE中config.properties文件乱码解决办法

    http://jingyan.baidu.com/article/ed2a5d1f3381d709f6be17f8.html ———————————————————————————…

    Java 2023年5月29日
    081
  • 类加载

    加载—–连接(验证—准备—解析)——初始化: 加载就是 将类的二进制字节码载入JVM中、将这个字节流代表的存…

    Java 2023年6月9日
    099
  • 内部类

    内部类 一种定义在类中的类,他们是嵌套关系。在 编译成功时,会生成多个 .class文件,分别是 &#x5916;&#x90E8;&#x7C7B;.clas…

    Java 2023年6月5日
    072
  • ch05 Java方法

    Java方法 何谓方法? System.out.println(); //类.对象.方法 Java方法是语句的集合,它们在一起执行一个功能。 方法是解决一类问题的步骤的有序组合 方…

    Java 2023年6月9日
    088
  • AQS源码二探-JUC系列

    本文已在公众号上发布,感谢关注,期待和你交流。 AQS源码二探-JUC系列 共享模式 这个方法是共享模式下获取资源失败,执行入队和等待操作,等待的线程在被唤醒后也在这个方法中自旋执…

    Java 2023年6月13日
    078
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球