零配置,零麻烦:MapStruct 的轻松对象映射之旅

news2025/2/26 18:00:27

欢迎来到我的博客,代码的世界里,每一行都是一个故事


在这里插入图片描述

零配置,零麻烦:MapStruct 的轻松对象映射之旅

    • 前言
    • MapStruct是什么
    • 快速上手:基础映射
    • 高级映射技巧
      • 1. 针对复杂类型的映射:
      • 2. 自定义映射逻辑:
    • MapStruct 的进阶用法
      • 1. 构造函数映射:
      • 2. 嵌套映射:
      • 3. 集合映射:
    • 伪出错
      • 结语:

前言

你是否曾为繁琐的对象映射代码而感到头疼?MapStruct 登场了!它不仅是 Java 开发者的得力助手,更是一个能够消除样板代码的魔法师。在这篇博客中,我们将一同踏上 MapStruct 的奇妙之旅,解锁它的神奇技能,让你的代码更为简洁、高效。

MapStruct是什么

MapStruct 是一个用于 Java 编程语言的对象映射框架,它的主要目标是简化 Java bean 类型之间的映射过程。在软件开发中,经常需要将一个对象的数据映射到另一个对象,而 MapStruct 通过注解处理器的方式,根据开发者提供的映射规则自动生成映射代码,从而减少手动编写重复、繁琐的映射代码的工作。

MapStruct 的定位是提供一种高性能、可扩展、易用的对象映射解决方案。相比其他对象映射框架,MapStruct 有以下优势:

  1. 性能优越: 由于 MapStruct 生成的映射代码是静态的,在编译期间就已经生成,因此它的性能通常比运行时反射的映射框架更高效。

  2. 可读性和维护性: MapStruct 生成的映射代码相对清晰简洁,易于阅读和维护。生成的代码包含了开发者定义的映射规则,也支持自定义转换逻辑。

  3. 类型安全: MapStruct 在编译期间就能够检测到潜在的映射错误,提供了类型安全性,减少了在运行时可能发生的错误。

  4. 灵活性: 支持自定义转换器,开发者可以通过注解指定特定的映射规则,也可以手动编写转换器以满足特定需求。

总体而言,MapStruct 是一款强大的对象映射框架,适用于各种 Java 项目,尤其在需要处理大量对象映射的场景下,能够提高开发效率并保证映射代码的质量。

快速上手:基础映射

快速上手 MapStruct 的基础映射需要完成一些简单的步骤。以下是一个基本的示例,演示如何创建一个简单的映射。

假设有两个类 SourceTarget,它们具有相似的字段,我们希望将一个对象映射到另一个对象。

  1. 引入 MapStruct 依赖:

    在项目的 pom.xml 文件中,添加 MapStruct 的依赖:

    <dependencies>
        <!-- 其他依赖 -->
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>1.4.2.Final</version> <!-- 查看最新版本 -->
        </dependency>
    </dependencies>
    
  2. 配置 Maven 插件:

    pom.xml 中,添加 MapStruct 的 Maven 插件配置:

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source> <!-- 适配你的 Java 版本 -->
                    <target>1.8</target> <!-- 适配你的 Java 版本 -->
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.mapstruct</groupId>
                <artifactId>mapstruct-maven-plugin</artifactId>
                <version>1.4.2.Final</version> <!-- 查看最新版本 -->
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                        <configuration>
                            <sourceDirectory>src/main/java</sourceDirectory>
                            <targetDirectory>target/generated-sources/mapstruct</targetDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    
  3. 创建源和目标类:

    // Source 类
    public class Source {
        private String name;
        private int age;
    
        // Getters and setters
    }
    
    // Target 类
    public class Target {
        private String name;
        private int age;
    
        // Getters and setters
    }
    
  4. 创建映射接口:

    import org.mapstruct.Mapper;
    import org.mapstruct.Mapping;
    
    @Mapper
    public interface SourceTargetMapper {
    
        @Mapping(source = "name", target = "name")
        @Mapping(source = "age", target = "age")
        Target sourceToTarget(Source source);
    }
    

    在上述代码中,@Mapper 注解表示这是一个 MapStruct 映射接口。@Mapping 注解用于指定源对象和目标对象字段的映射关系。

  5. 生成映射代码:

    在 Maven 项目中,运行以下 Maven 命令:

    mvn clean install
    

    这将触发 MapStruct 的注解处理器生成映射代码。

以上就是一个简单的 MapStruct 映射示例。请注意,这只是一个入门级的例子,MapStruct 还支持更复杂的映射,包括集合映射、嵌套映射等。通过适当的注解和配置,你可以灵活地定义映射规则,以满足项目的需求。

高级映射技巧

在 MapStruct 中,你可以使用高级映射技巧来处理复杂类型的映射,并定义自定义映射逻辑。以下是一些示例:

1. 针对复杂类型的映射:

假设有一个包含复杂类型的类 Person,其中包含了 Address 类型的地址信息。我们希望将 Person 类型映射到 PersonDTO 类型。

// Person 类
public class Person {
    private String name;
    private Address address;

    // Getters and setters
}

// Address 类
public class Address {
    private String city;
    private String street;

    // Getters and setters
}

// PersonDTO 类
public class PersonDTO {
    private String name;
    private String city;

    // Getters and setters
}

然后,创建映射接口并定义映射规则:

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;

@Mapper
public interface PersonMapper {

    @Mapping(source = "name", target = "name")
    @Mapping(source = "address.city", target = "city")
    PersonDTO personToPersonDTO(Person person);
}

在上述代码中,通过使用点号 . 来表示嵌套属性的映射关系,你可以轻松地处理复杂类型的映射。

2. 自定义映射逻辑:

有时候,你可能需要自定义映射逻辑以满足特定的需求。例如,如果需要将 Date 类型转换成字符串类型,可以使用自定义的转换器。

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
import java.text.SimpleDateFormat;

@Mapper
public interface CustomMapper {

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

    @Mapping(source = "date", target = "formattedDate", qualifiedByName = "dateFormat")
    Target customMapping(Source source);

    String dateFormat(java.util.Date date);

    class Target {
        private String formattedDate;

        // Getter and setter
    }

    class Source {
        private java.util.Date date;

        // Getter and setter
    }
}

在上述例子中,通过在映射接口中定义名为 dateFormat 的方法,并在 @Mapping 注解中使用 qualifiedByName 属性,实现了对 Date 类型的自定义转换。

这些是一些高级映射技巧的简单示例。MapStruct 提供了丰富的注解和配置选项,可以满足各种映射需求。根据项目的具体情况,你可以进一步探索 MapStruct 的文档以了解更多高级用法。

MapStruct 的进阶用法

MapStruct 提供了一些进阶用法,包括构造函数映射、嵌套映射和集合映射。下面分别介绍这些进阶用法:

1. 构造函数映射:

在某些情况下,你可能希望使用构造函数进行映射。MapStruct 允许你在映射接口中使用构造函数映射,这样可以更加灵活地处理对象创建过程。

假设有一个类 Person,它有一个包含多个参数的构造函数,我们希望将其映射到 PersonDTO 类型。

// Person 类
public class Person {
    private String name;
    private int age;

    // 构造函数
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // Getters and setters
}

// PersonDTO 类
public class PersonDTO {
    private String name;
    private int age;

    // 构造函数
    public PersonDTO(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // Getters and setters
}

然后,在映射接口中使用构造函数映射:

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;

@Mapper
public interface PersonMapper {

    @Mapping(target = "name", source = "name")
    @Mapping(target = "age", source = "age")
    PersonDTO personToPersonDTO(Person person);
}

MapStruct 会自动识别构造函数映射的关系,并生成相应的映射代码。

2. 嵌套映射:

MapStruct 支持嵌套映射,允许你在对象之间建立更复杂的映射关系。假设有一个嵌套的类结构,如 Order 包含 Customer,我们希望将 Order 映射到 OrderDTO,同时也映射 CustomerCustomerDTO

// Order 类
public class Order {
    private String orderId;
    private Customer customer;

    // Getters and setters
}

// Customer 类
public class Customer {
    private String name;
    private String address;

    // Getters and setters
}

// OrderDTO 类
public class OrderDTO {
    private String orderId;
    private CustomerDTO customer;

    // Getters and setters
}

// CustomerDTO 类
public class CustomerDTO {
    private String name;
    private String address;

    // Getters and setters
}

在映射接口中进行嵌套映射:

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;

@Mapper
public interface OrderMapper {

    @Mapping(source = "customer", target = "customer")
    OrderDTO orderToOrderDTO(Order order);

    @Mapping(source = "name", target = "name")
    @Mapping(source = "address", target = "address")
    CustomerDTO customerToCustomerDTO(Customer customer);
}

MapStruct 会根据映射接口中的定义自动生成嵌套映射代码。

3. 集合映射:

MapStruct 也支持集合的映射。假设有一个类 Library 包含了多个书籍 Book,我们希望将 Library 映射到 LibraryDTO,同时也映射其中的书籍列表。

// Book 类
public class Book {
    private String title;
    private String author;

    // Getters and setters
}

// Library 类
public class Library {
    private List<Book> books;

    // Getters and setters
}

// LibraryDTO 类
public class LibraryDTO {
    private List<BookDTO> books;

    // Getters and setters
}

// BookDTO 类
public class BookDTO {
    private String title;
    private String author;

    // Getters and setters
}

在映射接口中进行集合映射:

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;

@Mapper
public interface LibraryMapper {

    @Mapping(source = "books", target = "books")
    LibraryDTO libraryToLibraryDTO(Library library);

    @Mapping(source = "title", target = "title")
    @Mapping(source = "author", target = "author")
    BookDTO bookToBookDTO(Book book);
}

MapStruct 会根据映射接口中的定义自动生成集合映射代码。

这些是 MapStruct 的一些进阶用法,它们能够帮助你更灵活地处理复杂的映射场景。根据项目需求,你可以结合这些技巧,定制符合你业务逻辑的映射规则。

伪出错

1、报错 java.lang.ClassNotFoundException: Cannot find implementation for fun.todoitbo.botally.convert.TbBillConvert

这里要观察你的@Mapper注解,你可能错把mybatis中的@Mapper当成宝了

2、映射返回的结果都是null

出现上面的情况,要观察,是否存在目标类上没有set,get方法

3、我修改了源类或者目标类但是他没有生效

这里你需要clear一下,重新启动,因为它的实现方法只生成一次

结语:

通过本文的深度探索,相信你将对 MapStruct 有了全新的认识,并能够在你的项目中充分发挥它的威力。让我们一同掌握这门“魔法”,让代码变得更加清爽、优雅!

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

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

相关文章

【Sublime Text】| 01——下载安装注册

系列文章目录 【Sublime Text】| 01——下载软件安装并注册 【Sublime Text】| 02——常用插件安装及配置 失败了也挺可爱&#xff0c;成功了就超帅。 文章目录 前言1. 下载2. 安装3. 注册3.1 通过修改应用程序注册3.2 通过替换应用程序注册 感谢 前言 轻量代码编辑器有很多 之…

并发(4)

目录 16.sychronized修饰方法在抛出异常时&#xff0c;会释放锁吗&#xff1f; 17.多个线程等待同一个sychronized锁的时候&#xff0c;JVM如何选择下一个获取锁的线程&#xff1f; 18.sychronized是公平锁吗&#xff1f; 19.volatile关键字的作用是什么&#xff1f; 20.vo…

一文读懂 $mash 通证 “Fair Launch” 规则(幸运池玩法解读篇)

Solmash是Solana生态中由社区主导的铭文资产LaunchPad平台&#xff0c;该平台旨在为Solana原生铭文项目&#xff0c;以及通过其合作伙伴SoBit跨链桥桥接到Solana的Bitcoin生态铭文项目提供更广泛的启动机会。有了Solmash&#xff0c;将会有更多的Solana生态的铭文项目、资产通过…

2024年【危险化学品生产单位主要负责人】复审模拟考试及危险化学品生产单位主要负责人作业模拟考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年危险化学品生产单位主要负责人复审模拟考试为正在备考危险化学品生产单位主要负责人操作证的学员准备的理论考试专题&#xff0c;每个月更新的危险化学品生产单位主要负责人作业模拟考试祝您顺利通过危险化学品…

二、医学影像云平台(云PACS-RIS和HIS接口和检查登记)

和HIS接口 RIS和HIS或集成平台的对接&#xff0c;主要是用来获取检查信息&#xff0c;确认状态以及报告回传等工作。这里的接口文档一般都是由HIS来提供&#xff0c;文档里会给出很多概念&#xff0c;可能有病人ID号&#xff0c;身份证号&#xff0c;门诊号、住院号、体检号、…

数据矩阵集成可提高印刷电路板识别的准确性

在复杂的印刷电路板 (PCB) 世界中&#xff0c;准确的电路板元件识别对于简化故障排除至关重要。它确保电子设备高效运行。 本文将探讨数据矩阵码在提高 PCB 零件识别效率方面的作用。数据矩阵码提供了一种简单的解决方案来编码和解码与 PCB 组件相关的信息&#xff0c;在简化识…

添加jdk 11到环境变量的一种方法

添加jdk 11到环境变量的一种方法 1.jdk11可以直接在android studio 中下载&#xff0c; File --> Settings --> Build, Execution, Deployment --> Build Tools --> Gradle 下载jdk 11 &#xff0c;确认好下载路径 2.jdk11 添加到环境变量添加到环境变量 多个…

AI小蜜批量写作助手:多级指令,插件,GPTs满足不同写作需求

为什么会开发这个脚本&#xff1f; 爆文项目的核心是矩阵怼量 具体怎么做这里介绍很清楚了&#xff1a; AI爆文撸流量主保姆级教程3.0脚本写作教程&#xff08;解放双手&#xff09; 我在刚做爆文项目时候&#xff0c;都是手动操作&#xff0c;复制指令&#xff0c;组合指令…

设计模式之过滤器模式

目录 1.简介 2.过滤器的实现 2.1.过滤器的角色 2.2.类图 2.3.具体实现 3.过滤器模式的优点 4.过滤器模式的不足 5.适用的场景 1.简介 过滤器模式&#xff08;Filter Pattern&#xff09;或标准模式&#xff08;Criteria Pattern&#xff09;是一种结构型设计模式&…

静态代理还是动态代理?来聊聊Java中的代理设计模式

代理模式&#xff08;Proxy Design Pattern&#xff09;是一种结构型设计模式&#xff0c;为一个对象提供一个代理对象&#xff0c;然后使用代理对象控制对原对象的引用。即通过代理对象访问目标对象。被代理的对象可以是远程对象、创建开销大的对象或需要安全控制的对象。 一、…

JavaWeb——新闻管理系统(Jsp+Servlet)之jsp新闻查询

java-ee项目结构设计 1.dao:对数据库的访问&#xff0c;实现了增删改查 2.entity:定义了新闻、评论、用户三个实体&#xff0c;并设置对应实体的属性 3.filter&#xff1a;过滤器&#xff0c;设置字符编码都为utf8&#xff0c;防止乱码出现 4.service:业务逻辑处理 5.servlet:处…

Spring AI和Ollama

概述 Spring AI 不仅提供了与 OpenAI 进行API交互&#xff0c;同样支持与 Ollama 进行API交互。Ollama 是一个发布在GitHub上的项目&#xff0c;专为运行、创建和分享大型语言模型而设计&#xff0c;可以轻松地在本地启动和运行大型语言模型。 Docker环境安装Ollama 1.获取D…

第13课 利用openCV检测物体是否运动了

FFmpeg与openCV绝对是绝配。前面我们已经基本熟悉了FFmpeg的工作流程&#xff0c;这一章我们重点来看看openCV。 在前面&#xff0c;我们已经使用openCV打开过摄像头并在MFC中显示图像&#xff0c;但openCV能做的要远超你的想像&#xff0c;比如可以用它来实现人脸检测、车牌识…

个人笔记:分布式大数据技术原理(一)Hadoop 框架

Apache Hadoop 软件库是一个框架&#xff0c;它允许使用简单的编程模型&#xff0c;实现跨计算机集群的大型数据集的分布式处理。它最初的设计目的是为了检测和处理应用程序层的故障&#xff0c;从单个机器扩展到数千台机器&#xff08;这些机器可以是廉价的&#xff09;&#…

算法通关村第二十关-黄金挑战图的常见算法

大家好我是苏麟 , 今天聊聊图的常见算法 . 图里的算法是很多的&#xff0c;这里我们介绍一些常见的图算法。这些算法一般都比较复杂&#xff0c;我们这里介绍这些算法的基本含义&#xff0c;适合面试的时候装*&#xff0c;如果手写&#xff0c;那就不用啦。 图分析算法&#xf…

Qt/QML编程学习之心得:Timer的使用(22)

Qt中timer计时器如何使用? Timer的创建: void InitTimer(){myTimer = new QTimer(q);myTimer->setInterval(100); // 100msmyTimer->setSingleShot(true); //只运行一次的计时器QObject::connect(myTimer,SIGNAL(timeout()),q,SLOT(onTimeOut()));myTimer->start(…

(2023|NIPS,邻域分布预测,Wasserstein 距离)通过上下文预测改进基于扩散的图像合成

Improving Diffusion-Based Image Synthesis with Context Prediction 公和众和号&#xff1a;EDPJ&#xff08;添加 VX&#xff1a;CV_EDPJ 或直接进 Q 交流群&#xff1a;922230617 获取资料&#xff09; 目录 0. 摘要 3. 基础 4. ConPreDiff 4.1 扩散生成中的邻域上下…

Linux入门攻坚——11、Linux网络属性配置相关知识1

网络基础知识&#xff1a; 局域网&#xff1a;以太网&#xff0c;令牌环网&#xff0c; Ethernet&#xff1a;CSMA/CD 冲突域 广播域 MAC&#xff1a;Media Access Control&#xff0c;共48bit&#xff0c;前24bit需要机构分配&#xff0c;后24bit自己…

安装阿里云CLI之配置阿里云凭证信息

有时候需要再主机上通过 OpenAPI 的调用访问阿里云&#xff0c;并完成控制&#xff0c;此时就需要在服务器上安装阿里云CLI&#xff0c;并完成账号的设置。 1. 登录阿里云创建账号 1.1 点击阿里云头像 ——》 控制访问 ——》创建一个拥有DNS权限的用户 这个用户不用太多权限…

Service Weaver:Google开源基于分布式应用程序开发的框架,重新定义微服务边界

大家好&#xff0c;我是萧楚河&#xff0c;公众号&#xff1a;golang面试经典讲解&#xff0c;感谢关注&#xff0c;一起学习一起成长。一、前言 今年6月&#xff0c;一群谷歌员工&#xff08;由谷歌软件工程师Michael Whittaker领导&#xff09;发表了一篇名为“Towards Mode…