MapStruct丝滑替换BeanUtils.copyProperties

news2024/11/27 6:14:46

文章目录

    • 1 工具应用场景
    • 2 使用效果
    • 3 使用方法
      • 3.1 引入jar包
      • 3.2 指定lombok与MapStruct执行顺序
      • 3.3 定义@Mapper接口
      • 3.4 重新打包
    • 4 练习手段

1 工具应用场景

  BeanUtils.copyProperties拷贝对象同名属性,利用反射原理,耗时长,在对性能要求高的服务中不建议使用;

  MapStruct在编译阶段,生成对象拷贝的实现类,和手写拷贝代码相同,不存在反射耗时长问题;

MapStruct工具

2 使用效果

  本次使用在springboot项目中,在定义好mapStruct接口后,直接在使用的类中注入该对象,即可进行同名属性拷贝;

  FoodMapStructMapper为定义的接口类;

  调用点使用方法如下:

package maplegam.com.gateway.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class IndexController {

    @Autowired
    private FoodMapStructMapper foodMapStructMapper;

    @RequestMapping(value="/index", method= RequestMethod.POST)
    public String index(@RequestBody String msgBody) {

        Milk milk = new Milk();
        milk.setName("aaa");
        milk.setTaste("good");
        milk.setColor("white");

        Orange orange = foodMapStructMapper.toOrange(milk);
        System.out.println("orange:"+orange.toString());

        orange.setPrice("3.3");
        orange.setWeight("10kg");

        Apple apple = foodMapStructMapper.toApple(orange);
        System.out.println("apple:"+apple.toString());

        return msgBody;
    }
}

  打印结果为:

程序打印
  可以看到,orange从milk中拷贝得到了同名属性“name”,apple从orange中拷贝得到了同名属性“name”、“price”;

3 使用方法

3.1 引入jar包

  Springboot应用,使用MapStruct工具,需要引入mapStruct包,以及mapStruct-processor预编译包;

  引入方法如下:

  在pom.xml文件添加依赖包:

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.20</version>
</dependency>
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct</artifactId>
    <version>1.4.2.Final</version>
</dependency>

  这里的lombok放出来,是因为@Data注解太常用了,同样也是在编译阶段生成代码(主要是Get、Set方法),与MapStruct工具的@Mapper注解存在依赖关系,同时使用时,必须先指定执行@Data注解,生成Get、Set方法后,才能执行@Mapper注解,否则会出现异常。

3.2 指定lombok与MapStruct执行顺序

  在pom.xml文件的maven-compiler-plugin插件配置中,添加annotationProcessorPaths标签,来实现指定先后顺序效果;

  mapstruct-processor包也在这时指定;

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.8.1</version>
    <configuration>
        <source>1.8</source>
        <target>1.8</target>
        <encoding>UTF-8</encoding>
        <annotationProcessorPaths>
            <path>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.20</version>
            </path>
            <path>
                <groupId>org.mapstruct</groupId>
                <artifactId>mapstruct-processor</artifactId>
                <version>1.4.2.Final</version>
            </path>
        </annotationProcessorPaths>
    </configuration>
</plugin>

3.3 定义@Mapper接口

  MapStruct工具的功能很丰富,不仅仅能实现对象间同名属性的拷贝,由于本文只需要能做到替换BeanUtils.copyProperties,所以不对复杂场景进行举例;

  同名属性拷贝时,只需要定义接口方法即可,接口类内容如下:

package maplegam.com.gateway.controller;

import org.mapstruct.Mapper;

@Mapper(componentModel = "spring")
public interface FoodMapStructMapper {
    Apple toApple(Milk milk);
    Apple toApple(Orange orange);

    Milk toMilk(Apple apple);
    Milk toMilk(Orange orange);

    Orange toOrange(Apple apple);
    Orange toOrange(Milk milk);
}

  方法仅需要指定输入的类、输出的类即可,MapStruct工具会生成具体的impl实现类;

  componentModel需要指定为“spring”,这样生成的impl类,才会带@Component注解,否则无法通过@Autowired直接注入使用;

  接口中的对应的Milk、Apple、Orange类分别为:

  (1)Milk类

package maplegam.com.gateway.controller;

import lombok.Data;

@Data
public class Milk {
    public String name;
    public String taste;
    public String color;
}

  (2)Apple类

package maplegam.com.gateway.controller;

import lombok.Data;

@Data
public class Apple {
    public String name;
    public String price;
    public String taste;
}

  (3)Orange类

package maplegam.com.gateway.controller;

import lombok.Data;

@Data
public class Orange {
    public String name;
    public String price;
    public String weight;
}

3.4 重新打包

  需要注意,每次修改MapStruct工具的@Mapper接口类文件,都需要重新编译出包,这样生成的impl类才能和接口内容保持一致;

  impl类直接打包至最终的jar包中,在接口类的同级目录下,反编译后能看到内容如下:

package maplegam.com.gateway.controller;

import javax.annotation.Generated;
import org.springframework.stereotype.Component;

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2024-08-06T15:27:27+0800",
    comments = "version: 1.4.2.Final, compiler: javac, environment: Java 1.8.0_371 (Oracle Corporation)"
)
@Component
public class FoodMapStructMapperImpl implements FoodMapStructMapper {

    @Override
    public Apple toApple(Milk milk) {
        if ( milk == null ) {
            return null;
        }

        Apple apple = new Apple();

        apple.setName( milk.getName() );
        apple.setTaste( milk.getTaste() );

        return apple;
    }

    @Override
    public Apple toApple(Orange orange) {
        if ( orange == null ) {
            return null;
        }

        Apple apple = new Apple();

        apple.setName( orange.getName() );
        apple.setPrice( orange.getPrice() );

        return apple;
    }

    @Override
    public Milk toMilk(Apple apple) {
        if ( apple == null ) {
            return null;
        }

        Milk milk = new Milk();

        milk.setName( apple.getName() );
        milk.setTaste( apple.getTaste() );

        return milk;
    }

    @Override
    public Milk toMilk(Orange orange) {
        if ( orange == null ) {
            return null;
        }

        Milk milk = new Milk();

        milk.setName( orange.getName() );

        return milk;
    }

    @Override
    public Orange toOrange(Apple apple) {
        if ( apple == null ) {
            return null;
        }

        Orange orange = new Orange();

        orange.setName( apple.getName() );
        orange.setPrice( apple.getPrice() );

        return orange;
    }

    @Override
    public Orange toOrange(Milk milk) {
        if ( milk == null ) {
            return null;
        }

        Orange orange = new Orange();

        orange.setName( milk.getName() );

        return orange;
    }
}

  可以看到,impl类带着@Component注解,至此操作结束。

4 练习手段

  可以参考“3 使用方法”章节,在自己的项目中尝试用MapStruct工具,替换原本使用BeanUtils.copyProperties的地方,提升系统运行效率。

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

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

相关文章

SEO专家教你玩转谷歌外链!

​要想玩转谷歌外链&#xff0c;你得了解并掌握以下三种主流的外链策略。每种策略在不同情况下都有独到之处&#xff0c;具体怎么做&#xff0c;我来详细说说。 1.GPB独立站外链。这种方式主要是在数量较少的独立域名上发布全是dofollow的链接。关键在于确保链接的高质量和持久…

清洁能源时代,ARMxy智慧网关为风电行业保驾护航

在全球能源转型的背景下&#xff0c;清洁能源的发展成为了各国关注的焦点。风电作为一种可再生能源&#xff0c;具有巨大的发展潜力。而 ARMxy 工控机作为工业自动化领域的重要设备&#xff0c;在风电行业中发挥着至关重要的作用&#xff0c;为清洁能源的发展提供了有力的支持。…

角色模块开发

文章目录 &#x1f31e; Sun Frame&#xff1a;SpringBoot 的轻量级开发框架&#xff08;个人开源项目推荐&#xff09;&#x1f31f; 亮点功能&#x1f4e6; spring cloud模块概览常用工具 &#x1f517; 更多信息1.easycode生成基础代码1.配置2.将dao层代码剪切到mapper层3.A…

设计师的救星,效率插件大合集!有了它设计效率翻倍

作为一名设计师&#xff0c;我相信大家都有这样的痛苦经历&#xff1a;为了完成一个设计项目&#xff0c;得下载一堆工具&#xff0c;像 snipaste、pureref、eagle 等&#xff0c;每个都要单独下载、单独打开使用。还有一些效率工具&#xff0c;比如 utools 或 hapigo&#xff…

OpenCV图像滤波(6)高斯滤波函数GaussianBlur()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 函数使用高斯滤波器对图像进行模糊处理。 该函数使用指定的高斯核对源图像进行卷积。支持原位过滤。 高斯模糊是一种有效的图像平滑技术&#xf…

实验23.硬盘分区,并编写硬盘驱动程序

已完成实验 已完成实验链接 简介 实验 23. 硬盘分区&#xff0c;并编写硬盘驱动程序 总结 创建硬盘并分区 加载硬盘分区 实现 printk 使能硬盘中断 interrupt.c idel 线程,主线程阻塞后此线程保底 thread.c sleep 函数 timer.c 加载分区信息 ide.c 创建硬盘 fdisk …

[Web服务器] 简易静态Web服务器的搭建

什么是Web服务器 可以为发出请求的浏览器提供静态文档的程序。 平时我们浏览百度新闻数据的时候&#xff0c;每天的新闻数据都会发生变化&#xff0c;那访问的这个页面就是动态的&#xff0c;而我们开发的是静态的&#xff0c;每天访问我们自己的静态web服务器&#xff0c;页面…

宠物托运网站如何搭建?5步帮你吸引70%顾客!

引言 随着人们生活水平的提高和宠物文化的普及&#xff0c;越来越多的宠物主人开始选择带着自己的宠物一同旅行或搬迁至新的城市。这一趋势催生了宠物托运服务行业的快速发展&#xff0c;而一个专业、高效的宠物托运网站则成为了连接宠物主人与托运服务提供商之间不可或缺的桥…

七夕情人节送什么礼物?四款好物分享,情侣必看!

在浪漫的七夕情人节&#xff0c;为心爱的人挑选一份特别的礼物是每对情侣表达爱意的重要方式。市场上琳琅满目的选择让人眼花缭乱&#xff0c;究竟什么样的礼物能触动TA的心弦&#xff1f;本篇分享将为您精选四款既实用又充满情意的好物&#xff0c;无论是甜蜜的开始还是长久的…

【区块链+医疗健康】医链 - 区块链医疗信息管理系统 | FISCO BCOS应用案例

根据《“十四五”规划和 2035 远景目标纲要》&#xff0c;我国在“十四五”时期将全面推进医疗信息化建设。工信部等部 门联合发布《关于加快推动区块链技术应用和产业发展的指导意见》&#xff0c;促进区块链在医疗健康等公共服务领域开 展应用&#xff0c;促进业务协同办理。…

1. dact-admin 中如何发布一个表并添加到导航栏

1.页面脚手架中根据自己需求选择生成的文件例如模型、控制器、翻译文件、数据库迁移文件等 访问 http://【你的域名】/admin/helpers/scaffold 例如&#xff1a; http://localhost:8000/admin/helpers/scaffold 2. 新建好之后来到路由文件 路径随便写&#xff0c;当然按照惯…

[C++] 模板进阶:特化与编译链接全解析

文章目录 非类型模板类型形参非类型模板参数代码示例 **模板的特化**为什么要有模板的特化函数模板特化使用场景与示例函数模板特化的实现细节 类模板特化全特化示例 偏特化部分优化通过进一步限制模板参数进行特化偏特化为指针类型示例&#xff1a;偏特化为引用类型示例&#…

红酒与午后:悠闲时光的惬意选择

阳光透过窗棂&#xff0c;轻轻洒在木质的茶几上&#xff0c;斑驳的光影交织出一幅静谧而温暖的画面。在这宁静的午后&#xff0c;一瓶洒派红酒&#xff08;Bold & Generous&#xff09;静静地摆放在那里&#xff0c;仿佛正等待着与你一同开启一段悠闲的品酒时光。 一、午后…

【往届均已完成EI、SCOPUS检索】第四届电气工程与计算机技术国际学术会议(ICEECT 2024,9月27-29)

第四届电气工程与计算机技术国际学术会议&#xff08;ICEECT2024&#xff09;将于9月27日-29日在哈尔滨举办。 会议主要围绕"电路与系统"、“电气工程材料”、“计算机视觉”、“计算机技术”等专业研究领域展开讨论。旨在为气工程、计算机技术等领域的专家学者及企业…

Figma汉化教程

Figma汉化教程&#xff0c;需要 5 步 第一步&#xff1a;我们打开一个Figma中文社区网站 https://www.figma.cool/cn。我们点击左上角的Figma汉化&#xff0c;进入Figma汉化安装的页面。 第二步&#xff1a;在Figma 软件汉化页面中&#xff0c;选择谷歌浏览器汉化&#xff0c;点…

Litestar GET function blocks OpenAI

题意&#xff1a;Litestar GET 函数阻塞 OpenAI 问题背景&#xff1a; When I transfer function to litestar, it suddenly stops OpenAI from returning a completion. I can print to console every declared variable except answer: 当我将函数传递给 litestar 时&#…

解析蚂蚁T21 190T 算力与能效的新突破

蚂蚁T21 190T 的参数如下&#xff1a; ● 产生币种&#xff1a;B & T & C ● 额定算力&#xff1a;190T ● 额定功耗&#xff1a;3610W ● 功耗比&#xff1a;19.0J/T ● 额定电压&#xff1a;380~415V ● 芯片参数&#xff1a;采用全新的5nm芯片技术&#xff08…

Linux笔记 --- Linux内核链表

Linux 内核链表 经过上一小节的分析&#xff0c;我们知道了传统链表的先天缺陷&#xff1a;没有将具体的数据从组织这些数据的逻辑结构中剥离&#xff0c;而Linux内核链表的思路&#xff0c;正是从一方面着手&#xff0c;追根溯源直抵病灶&#xff0c;彻底颠覆了传统链表&…

Linux内网环境部署thingsboard(离线部署)

先说明一下内网部署的环境,我这里是安装的thingsboard3.6.4 下面所有环境包的版本都是基于这个版本 我们需要安装jdk11,postgres数据库&#xff0c;这里注意下jdk必须使用rpm方式安装&#xff0c;要不后面安装Thingsboard会提示你没有检测到jdk. 下面我们就一步一步来 1.先下…

同城货运软件开发货运搬家系统源码基于Java开发的货运平台

一.管理端配置及操作 1.服务配置 添加:服务,给服务添加车型和车厢,以及收费金额 2.用户中心 分为普通用户 师傅用户 和推广员用户; 推广员用户的一二级分佣不为0,可给推广员设置一二级佣金 3.车厢/车型管理 给服务添加车厢 和车型,选择 服务后,只能选择该服务关联的车型和…