对象拷贝初识mapstruct及与lombok的配置

news2024/11/14 21:38:36

        项目中用到对象拷贝,做一个修改历史记录保存的功能,使用Spring AOP自定义注解实现修改记录的保存,历史记录表和业务表的字段差不多,保存的时候需要用到对象拷贝。下面是一些对象拷贝的工具,前3个都用过,这次想尝试一下新的mapstruct,喜新厌旧一波。

1. 对象拷贝常见的工具类

1.1 Apache 的BeanUtils的copyProperties方法

特点:浅拷贝,属性还是指向原本对象的引用。字段名称相同,类型不同无法进行赋值,基本类型字段和引用对象可以映射。

1.2 SpringUtils的copyProperties方法

特点:同Apache,效率比Apache高,参数的位置与Apache不同

1.3 序列化(JSON)

特点:深拷贝,性能低,耗时长(序列化-反序列化)。基本类和引用对象可以映射。字段名称相同,类型不同可以赋值。

1.4 MapStruct

特点:深拷贝,灵活(可自主配置字段映射关系),可以配置多对一映射关系。效率高,准确(编译器代码生成,源码就是get、set方法)。

2. MapStruct初次使用配置过程

2.1典型的常规操作,这里记录我配置过程中遇到的问题,仅供参考,可以不看,直接看后面的正确配置;

2.2决定要用,就先Bing了一把,大体一看内容还算完整,有配置,有测试,还有代码和源码,一看感觉不难,哐哐哐一顿配置,然后不出意外的报错了;

2.3我用的是公司封装的框架,耦合高,有几点和网上说的不一样:

一个是我的实体类有继承;

二个是我继承的实体类没有用lombok插件,我用了;

这两点对我造成了困扰,但是不影响使用MapStruct。

遇到的异常有:

一个是“No property named “XXX“ exists in source parameter(s). Did you mean news”;

No property named “XXX“ exists in source parameter(s). Did you mean news

一个是lombok插件的问题,提示java找不到符号(解决第一个问题过程中,越解决问题越严重);

2.4配置过程

一开始,导入maven依赖,根据网上的博文,注意lombok和mapstruct的版本,选择了同一个年份的版本。这里我用的是lombok插件,查看版本后选择的mapstruct版本,发布的年份一样,但是月份不一样,就配置上了。

然后就可以添加代码,写了Mapper和拷贝方法,就开始单元测试,问题来了,提示No property named “XXX“ exists in source parameter(s),虽然属性我可以点进去,但是就是报错。我怀疑是版本问题,就开始重新捣鼓版本,各种尝试,没解决。只好去官网,发现官网上的配置还添加了maven-compiler-plugin插件,我也加上,然而问题更严重了,冲突更厉害,直接影响我的lombok代码,改了3个d插的件版本,未解决,只能还原回去,确认就是版本问题。因为MapStruct原理类似于lombok,都是在编译期进行实现。只能继续看官网文档,最终配置成功。有问题找官网准没错。

3. MapStruct的正确配置,这里介绍maven方式

3.1项目pom文件添加依赖和plugins

<properties>
    <java.version>1.8</java.version>
    <org.mapstruct.version>1.5.5.Final</org.mapstruct.version>
    <org.projectlombok.version>1.18.26</org.projectlombok.version>
    <lombok-mapstruct-binding.version>0.2.0</lombok-mapstruct-binding.version>
</properties>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>${org.projectlombok.version}</version>
    <scope>provided</scope>
</dependency>



<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct</artifactId>
    <version>${org.mapstruct.version}</version>
</dependency>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.11.0</version>
    <configuration>
        <source>1.8</source>
        <target>1.8</target>
        <annotationProcessorPaths>
            <path>
                <groupId>org.mapstruct</groupId>
                <artifactId>mapstruct-processor</artifactId>
                <version>${org.mapstruct.version}</version>
            </path>
            <path>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${org.projectlombok.version}</version>
            </path>
            <path>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok-mapstruct-binding</artifactId>
                <version>${lombok-mapstruct-binding.version}</version>
            </path>
        </annotationProcessorPaths>
    </configuration>
</plugin>

3.2编写Mapper,我这里就用官网的代码了

CarMapper.java

@Mapper

public interface CarMapper {

CarMapper INSTANCE = Mappers.getMapper( CarMapper.class );

@Mapping(source = "numberOfSeats", target = "seatCount")

CarDto carToCarDto(Car car);

}

Car.java

public class Car {

    private String make;

    private int numberOfSeats;

    private CarType type;

    //constructor, getters, setters etc.

}

CatDto.java

public class CarDto {

    private String make;

   private int seatCount;

    private String type;

    //constructor, getters, setters etc.

}

测试方法:

@Test

public void shouldMapCarToDto() {

    //given

    Car car = new Car( "Morris", 5, CarType.SEDAN );

    //when

    CarDto carDto = CarMapper.INSTANCE.carToCarDto( car );

    //then

    assertThat( carDto ).isNotNull();

    assertThat( carDto.getMake() ).isEqualTo( "Morris" );

    assertThat( carDto.getSeatCount() ).isEqualTo( 5 );

    assertThat( carDto.getType() ).isEqualTo( "SEDAN" );

}

4.总结:初次使用,没啥经验总结,这个项目也是简单使用,如有机会再深入了解。

4.1 lombok版本和MapStruct版本可以不必严格保持时间上对应。我这里用的就是最新的MapStruct版本和我IDE中lombok的插件版本,并不冲突。

4.2 如果两个对象中变量命名一致可以不用配置@Mapping。

/**
     * 这个方法就是用于实现对象属性复制的方法
     *
     * @param xx 这个参数就是源对象,也就是需要被复制的对象
     * @return 返回的是目标对象,就是最终的结果对象
     * @Mapping 用来定义属性复制规则 source 指定源对象属性 target指定目标对象属性
     */
    @Mappings({@Mapping(source = "id", target = "detailId")})

4.3有事找官网

官网:MapStruct – Java bean mappings, the easy way!

再不行找官网的例子:

 GitHub - mapstruct/mapstruct-examples: Examples for using MapStruct

4.4 maven-compiler-plugin插件的版本根据你自己需要选择,不影响。主要的是annotationProcessorPaths的配置,我参考的是官方例子里面的mapstruct-lombok

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/833520.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

某银行软件测试笔试题

&#xff08;时间90分钟&#xff0c;满分100分&#xff09; 考试要求&#xff1a;计算机相关专业试题 一、填空题&#xff08;每空1分&#xff0c;共10分&#xff09; 1. ______验证___是保证软件正确实现特定功能的一系列活动和过程。 2. 按开发阶段分&#xff0c;软件测试可…

HTTPS-RSA握手

RSA握手过程 HTTPS采用了公钥加密和对称加密结合的方式进行数据加密和解密 RSA握手是HTTPS连接建立过程中的一个关键步骤&#xff0c;用于确保通信双方的身份验证和生成对称加密所需的密钥 通过RSA握手过程&#xff0c;客户端和服务器可以协商出一个共享的对称密钥&#xff0c;…

操作系统——什么是操作系统

文章目录 操作系统的概念操作系统的特征并发和并行共享虚拟异步 操作系统的功能管理计算机系统的资源作为用户和计算机硬件之间的接口 操作系统的发展历程操作系统的运行环境CPU运行模式异常和中断系统调用 操作系统结构操作系统的引导虚拟机容器 操作系统的概念 操作系统是指…

安全渗透知识总结二

目录 一、html实体编码 1、Unicode字符编码 2、字符的数字表示 3、常见实体编码 4、url 协议 主机 http状态码 http常用的状态码 端口 常见协议端口 查询参数 锚点 url字符 urlcode字符 绝对url和相对url 二、字符编码 Ascll字符集 html字符集 html的url编码 …

2023年华数杯C题

C 题 母亲身心健康对婴儿成长的影响 母亲是婴儿生命中最重要的人之一&#xff0c;她不仅为婴儿提供营养物质和身体保护&#xff0c; 还为婴儿提供情感支持和安全感。母亲心理健康状态的不良状况&#xff0c;如抑郁、焦虑、 压力等&#xff0c;可能会对婴儿的认知、情感、社会行…

Docker-Compose编排与部署

目录 Docker Compose Compose的优点 编排和部署 Compose原理 Compose应用案例 安装docker-ce 阿里云镜像加速器 安装docker-compose docker-compose用法 Yaml简介 验证LNMP环境 Docker Compose Docker Compose 的前身是 Fig&#xff0c;它是一个定义及运行多个 Dock…

【软考中项】系统集成项目管理工程师2023下半年报名考试攻略

软考中级系统集成项目管理工程师2023下半年考试时间&#xff1a; 2023年下半年软考中级系统集成项目管理工程师的考试时间为11月4日、5日。考试时间在全国各地一致&#xff0c;建议考生提前备考。共分两科&#xff0c;第一科基础知识考试具体时间为9:00到11:30&#xff1b;第二…

《信息系统项目管理师教程(第4版)》软考高级 第六章 项目管理概论知识点、思维导图整理

第六章 项目管理概论 考情分析 Part1 PMBOK的发展&#xff08;无考点&#xff09;Part2 项目基本要素 一、项目基础 1、独特的产品、服务或成果2、临时性工作3、项目驱动变更4、项目创造业务价值5、项目启动背景 &#xff08;与组织的战略目标和项目的业务价值关联&#xff09…

木马病毒怎么回事?带你深度分析了解木马病毒!

一、病毒简介 SHA256:3110f00c1c48bbba24931042657a21c55e9a07d2ef315c2eae0a422234623194 MD5:ae986dd436082fb9a7fec397c8b6e717 SHA1:31a0168eb814b0d0753f88f6a766c04512b6ef03 二、行为分析 老套路&#xff0c;火绒剑监控&#xff1a; 这边可以看见创建了一个exe&#x…

Anaconda安装以及如何创建新环境

一、安装&#xff1a; 官网下载安装包&#xff1a;Anaconda | The World’s Most Popular Data Science Platform ok. 二、创建新的python环境&#xff1a; &#xff08;这个在学习别人的开源代码时常用&#xff0c;因为自己的环境常常会与别人项目中的环境不兼容&#xff09…

Android Studio 屏幕适配

Android开发屏幕适配流程 首先studio中没有ScreenMatch这个插件的&#xff0c;下去现在这个插件 点击File->settings->Plugins->(搜索ScreenMatch插件)&#xff0c;点击下载&#xff0c;应用重启Studio即可&#xff0c;如下图 在values下 创建dimens.xml&#xff0c…

[数据集][目标检测]遛狗不牵绳数据集VOC格式-1980张

数据集格式&#xff1a;Pascal VOC格式(不包含分割路径的txt文件和yolo格式的txt文件&#xff0c;仅仅包含jpg图片和对应的xml) 图片数量(jpg文件个数)&#xff1a;1980 标注数量(xml文件个数)&#xff1a;1980 标注类别数&#xff1a;5 标注类别名称:["dog","p…

Cpp9 — map和set

map和set STL分为序列式容器&#xff08;vector、list、deque&#xff09;和关联式容器&#xff08;map、set&#xff09; 序列式容器&#xff1a;数据与数据之间没有很强的联系。&#xff08;各个数据之间没什么关联&#xff09;。底层为线性序列的数据结构&#xff0c;里面…

Go语言入门:从零开始的快速指南

文章目录 引言Go语言的诞生背景Go 语言的特性安装Go语言环境集成开发环境安装第一个Go程序Go 源代码的特征解读 引言 Go语言&#xff08;也称为Golang&#xff09;是一种开源的、静态类型的编程语言&#xff0c;由Google开发。它的设计目标是简单、高效、安全、并且易于学习和…

使用docker 搭建nginx + tomcat 集群

创建3个Tomcat容器&#xff0c;端口分别映射到 8080,8081,8082&#xff0c;使用数据卷挂载&#xff0c;分别将宿主机目录下的 /opt/module/docker/tomcat3/ROOT1/&#xff0c;/opt/module/docker/tomcat3/ROOT2/&#xff0c;/opt/module/docker/tomcat3/ROOT2/ 挂载到 容器内部…

安防监控视频汇聚EasyCVR电子地图定位偏移是什么原因?

安防监控EasyCVR视频汇聚综合管理平台具有强大的数据接入、处理及分发能力&#xff0c;平台可提供视频监控直播、云端录像、云存储、录像检索与回看、告警上报与查询、平台级联、云台控制、语音对讲、电子地图、轨迹跟踪、H.265自动转码等视频能力。 在视频监控管理平台TSINGSE…

什么样的跨网文件安全交换系统 可实现安全便捷的文件摆渡?

进入互联网时代&#xff0c;网络的运算和数据管理能力助力各个行业高速发展&#xff0c;但同样带来了一些网络安全隐患&#xff0c;网络攻击、数据窃取、敏感信息泄露等问题。为此&#xff0c;我国出台了系列政策来全面提升银各行业系统网络安全整体防护水平&#xff0c;其中“…

微信小程序中的全局数据共享(状态管理)使用介绍

开发工具&#xff1a;微信开发者工具Stable 1.06 一、状态管理简介 微信小程序全局状态是指可以在不同页面之间共享的数据或状态。 它可以存储用户的登录状态、个人信息、全局配置信息等。 二、安装MobX 1、安装NPM 在资源管理器的空白地方点右键&#xff0c;选择“在外部…

在Volo.Abp微服务中使用SignalR

假设需要通过SignalR发送消息通知&#xff0c;并在前端接收消息通知的功能 创建SignalR服务 在项目中引用 abp add-package Volo.Abp.AspNetCore.SignalR在Module文件中添加对模块依赖 [DependsOn(...typeof(AbpAspNetCoreSignalRModule))] public class IdentityApplicati…

JavaEE 面试常见问题

一、常见的 ORM 框架有哪些&#xff1f; 1.Mybatis Mybatis 是一种典型的半自动的 ORM 框架&#xff0c;所谓的半自动&#xff0c;是因为还需要手动的写 SQL 语句&#xff0c;再由框架根据 SQL 及 传入数据来组装为要执行的 SQL 。其优点为&#xff1a; 1. 因为由程序员…