MapStruct 的进阶用法!!

高效、优雅的对象copy之MapStruct入门到精通,实战踩坑版 大家在开发中,最让人头疼的就是:对象之间的拷贝,前端的VO和数据库的Entity不一致!性能最好的就是手动set,主要是枯燥且无技术含量,不仅耗费大量时间而且很容易出错;所以我们要成为优秀的程序员,要多借助轮子,开发效率事半功倍,开发技能也是增长不少!如果系统性能没有要求,怎么实现都是好的,但是我们要有追求哈,追求高质量!每个东西都有存在的价值,不要捧一踩一哈!MapStruct是基于JSR 269的Java注释处理器,用于生成类型安全的 Bean 映射类。 阅读详情

前言

MapStruct 是一个 Java 编译时注解处理框架,用来自动化将一种 Java Bean 对象映射成另一种类型的对象。

该框架的主要目标是使开发人员在尽可能少的代码和最低的运行时间成本下实现属性映射。MapStruct 通过在编译时生成代码来实现这点,这与大多数其他 Java Bean 映射框架在运行时通过反射进行映射形成了鲜明对比。

MapStruct 具有以下主要特性:

  • 简洁: 简化了 Java Beans 之间转换的代码,自动生成使用简单的赋值语句完成的映射实现。

  • 性能优秀: 由于 MapStruct 是在编译时生成代码,不涉及任何反射,因此执行映射的性能优越。

  • 安全: 通过在编译时生成映射代码,MapStruct 提供了类型安全的映射,并能在编译时就发现潜在的错误。

  • 灵活: 可通过自定义转换方法、类型转换和映射策略等来满足复杂的映射需求。

  • 良好的 IDE 支持: 由于 MapStruct 是编译时工具,所以拥有良好的 IDE 集成,如代码自动完成、错误高亮等。

总的来说, MapStruct 是一个强大且灵活的映射框架,很好的解决有关对象转换的问题,实现了代码的简洁和性能的兼顾。MapStruct的常规用法,网上有很多教程了,本文将列举一些进阶用法,方便日常开发使用。

expression

在转化的时候,执行 java 表达式,直接看例子:

@Mapper(componentModel = "spring")
public interface MyMapper {
    @Mapping(target = "createTime", expression = "java(System.currentTimeMillis())")
    Target toTarget(Source source);
}

转化成 target 对象时,createTime字段的值,会设置为System.currentTimeMillis(),生成的代码如下:

@Component
public class MyMapperImpl implements MyMapper {

    @Override
    public Target toTarget(Source source) {
        Target target = new Target();
        target.setCreateTime( System.currentTimeMillis() );
        return target;
    }
}

qualifiedByName

做映射时,默认情况下,从source 字段到target 字段是直接使用 get/set,如下:

@Data
public class Source {
    private String name;
}

@Data
public class Target {
    private String name;
}
    

@Mapper(componentModel = "spring")
public interface MyMapper {
    Target toTarget(Source source);
}

生成的转化代码类如下:

@Component
public class MyMapperImpl implements MyMapper {

    @Override
    public Target toTarget(Source source) {
        if ( source == null ) {
            return null;
        }

        Target target = new Target();

        // 无脑 set/get
        target.setName( source.getName() );

        return target;
    }
}

如果这种直接的 set/get 无法满足需求,比如需要把 name 转化成大写格式,那么可以使用qualifiedByName:

@Mapper(componentModel = "spring")
public interface MyMapper {
    @Mapping(target = "name", source = "name", qualifiedByName = "toUpperCase")
    Target toTarget(Source source);

    @Named("toUpperCase")
    default String toUpperCase(String value) {
        // 这里写转换大写的逻辑
        return value == null ? null : value.toUpperCase();
    }
}

生成的代码如下:

@Component
public class MyMapperImpl implements MyMapper {

    @Override
    public Target toTarget(Source source) {
        if ( source == null ) {
            return null;
        }

        Target target = new Target();

        target.setName( toUpperCase( source.getName() ) );

        return target;
    }
}

nullValueMappingStrategy

如果 source 为 null 时,对应的 target 的处理策略,默认是 NullValueMappingStrategy.RETURN_NULL,即 target 中对应的字段也设置为 null。

但有时候设置为 null 可能不符合我们的需求,比如 target 中有个 List ids,我们希望如果 source 中ids 为 null 时,target 的 ids 设置为空 list。这时候可以使用nullValueMappingStrategy策略中的NullValueMappingStrategy.RETURN_DEFAULT。

nullValueMappingStrategy 可以使用在某个方法上(只对该方法生效),也可以使用在类上(对类中的所有方法都生效),如下:

@Component
public class MyMapperImpl implements MyMapper {

    @Override
    public Target toTarget(Source source) {
        if ( source == null ) {
            return null;
        }

        Target target = new Target();

        target.setName( source.getName() );
        List<Integer> list = source.getIds();
        if ( list != null ) {
            target.setIds( new ArrayList<Integer>( list ) );
        }
        else {
            target.setIds( null );
        }

        return target;
    }
}

指定NullValueMappingStrategy.RETURN_DEFAULT策略后:

@Mapper(componentModel = "spring",
        nullValueMappingStrategy = org.mapstruct.NullValueMappingStrategy.RETURN_DEFAULT)
public interface MyMapper {

    Target toTarget(Source source);
}

@Component
public class MyMapperImpl implements MyMapper {
    @Override
    public Target toTarget(Source source) {

        Target target = new Target();

        if ( source != null ) {
            target.setName( toUpperCase( source.getName() ) );
            List<Integer> list = source.getIds();
            if ( list != null ) {
                target.setIds( new ArrayList<Integer>( list ) );
            }
            else {
                target.setIds( new ArrayList<Integer>() );
            }
        }

        return target;
    }
}

可以看到,当 source 或者 source.ids 为 null 时,返回的 target 和 target.ids 都是默认的空值(空对象+空 list)。

Decorator

你可以通过创建一个 Decorator 类来对你的方法进行修饰并实现全局处理。

以下是一个例子:

public abstract class YourMapperDecorator implements YourMapper {

    private final YourMapper delegate;

    public YourMapperDecorator(YourMapper delegate) {
        this.delegate = delegate;
    }

    @Override
    public Target toTarget(Source source) {
        Target result = delegate.toTarget(source);
        if (result != null) {
            if (result.getField() == null) {
                result.setField("");
            }
            // 你可以在这里对其他字段进行同样的处理...
        }
        return result;
    }
}

然后你只需在你的 Mapper 接口上添加 @DecoratedWith 注解:

@Mapper
@DecoratedWith(YourMapperDecorator.class)
public interface YourMapper {
    Target toTarget(Source source);
}

这样,每次调用 toTarget 方法时,YourMapperDecorator 中的实现会被调用。在这里,你可以实现任何你想要的逻辑,例如对空字段赋予特定的默认值。

MapStruct进阶指南:10个你可能不知道的高级用法(SpringBoot整合版) 本文深入探讨了MapStruct在SpringBoot项目中的10个高级用法,包括条件映射、自定义表达式、生命周期回调、枚举映射及与Spring框架的深度集成等。通过员工管理、电商订单等实战案例,帮助开发者掌握复杂DTO转换技巧,提升代码的灵活性、可维护性与性能。 阅读详情

相关推荐

mapstruct的用法-qualifiedByName

qualifiedByName的意思就是使用这个Mapper接口中的指定的默认方法去处理这个属性的转换,而不是简单的get set。网上一直没找到... 可用于格式化小数位等,在po转换为vo时就已格式化小数位完成,所以不必单独再写代码处理小数位。 1 引用pom1 ,能正常使用mapstruct的注解,但不会生成Impl类 &lt;!-- https://mvnrepos...

Top5软件工程硕士,先后在京东、字节从事多年Java后端开发、实时和离线大数据开发 1万+

MapStruct高级使用姿势

MapStruct是一个Java注解处理器,用于自动生成类型安全的、高性能的Java Bean映射器。它可以帮助我们在Java项目中实现对象之间的转换,而无需编写繁琐的映射代码。

超级博客 3284

Power Automate实战:用SharePoint REST API批量处理列表数据(附JSON解析技巧)

本文深入探讨了如何利用Power Automate调用SharePoint REST API实现列表数据的批量自动化处理。文章详细解析了API的协同工作原理、高效的数据获取与筛选技巧,并重点分享了JSON数据解析的核心难点与实战解决方案,旨在帮助企业用户构建稳定可靠的数据处理流程,提升运营效率。

coffee的博客 771

mapstruct高级使用方法

原文地址:https://mp.weixin.qq.com/s/3PjpKKcVifqYluUpXYsyrA 背景介绍 在微服务盛行的当下,相信对领域驱动设计都不陌生,在领域驱动设计中,我们经常要处理将DTO转换成Domain,Domain转成Entity等各类对象相互转换,在没有接触mapstruct之前,相信大多数人都是使用Spring框架自带的BeanUtils或者直接使用getter/setter方法进行属性赋值,如果我们采用BeanUtils工具类的copyProperty进行转换,除了性能低之外

m0_56602396的博客 1692

Android BluetoothSocket

BluetoothSocket是Android中用于在蓝牙设备之间进行数据传输的一种Socket。它提供了一种类似于TCP/IP协议的数据传输方式,可以在两个设备之间建立一个虚拟的通信管道,使得两个设备之间可以进行数据的传输和接收。BluetoothSocket可以用于客户端和服务端之间的通信,通过BluetoothSocket可以实现数据的双向传输。

liuning1985622的博客 1478

Ansys Zemax | 利用OpticStudio实现衍射光学元件(DOE)与超透镜(metalens)的高效建模与验证

本文详细介绍了如何利用Ansys Zemax的OpticStudio软件实现衍射光学元件(DOE)与超透镜(metalens)的高效建模与验证。通过混合建模策略、相位面等效建模法、POP与FDTD联合验证等多种方法,帮助工程师快速解决跨尺度仿真难题,提升设计效率与精度。文章还分享了实战案例与高级技巧,适用于AR、医疗内窥镜等应用场景。

weixin_29268331的博客 501

MapStruct快速入门(什么是MapStruct、MapStruct与BeanUtils.copyProperties方法有什么区别,MapStruct进阶用法,MapStruct的实现原理)

MapStruct快速入门(什么是MapStruct、MapStruct与BeanUtils.copyProperties方法有什么区别,MapStruct进阶用法,MapStruct的实现原理)

聂可以的博客 4817

MIPI CSI-2数据加扰技术解析:LFSR实现与多通道同步策略

本文深入解析了MIPI CSI-2协议中的数据加扰技术,该技术通过线性反馈移位寄存器(LFSR)对图像数据进行随机化处理,旨在有效降低高速传输中的电磁干扰。文章详细阐述了LFSR的工作原理、D-PHY与C-PHY物理层不同的初始化与同步策略,并探讨了多通道同步的实现方法,为高速接口的EMC设计与调试提供了实践指导。

weixin_29207149的博客 386

MapStruct的用法总结及示例

比dozer更好用的java对象属性映射复制工具MapStuct的用法及代码示例

小蜜蜂1010的博客 5552

android studio 2022打开了v1 签名但是生成的apk没有v1签名问题

我使用了Android Studio Flamingo | 2022.2.1 Patch 2版本的IDE编译了一个apk,但是apksigner查看apk的签名信息时,发现只有v2签名,没有v1签名。试着改小一下minSdkVersion 为23重新编译apk,再检测一下签名版本v1居然打开了!参考网上搜索到的方法,手动在build.gradle里面添加。但是编译出来的apk还是只有v2的签名。里面提到了v1签名还和。

hedalei的博客 466

RT-DETR训练前的准备,将数据集划分成训练集、测试集验证集(附完整脚本及使用说明)

在计算机视觉领域,当我们着手训练一个模型时,。其中,将数据集划分为和更是一项基础性且关键的操作。这篇博客分析了这一划分背后的原因、其重要意义以及如何通过代码实现,帮助大家更好地理解和运用这一技巧,。

Limiiiing的博客 911

MapStruct 进阶用法

MapStruct 是一个 Java 编译时注解处理框架,用来自动化将一种 Java Bean 对象映射成另一种类型的对象。该框架的主要目标是使开发人员在尽可能少的代码和最低的运行时间成本下实现属性映射。MapStruct 通过在编译时生成代码来实现这点,这与大多数其他 Java Bean 映射框架在运行时通过反射进行映射形成了鲜明对比。简洁:简化了 Java Beans 之间转换的代码,自动生成使用简单的赋值语句完成的映射实现。

jjc4261的博客 1011

《信息化项目文档模板十二——业务需求新增/变更审批确认表 》

系列文章目录 《信息化项目文档模板一——项目需求说明书》 《信息化项目文档模板二——项目启动会文档模板》 《信息化项目文档模板三——会议纪要模板》 《信息化项目文档模板四——系统项目蓝图设计模板》 《信息化项目文档模板五——系统详细设计模板》 《信息化项目文档模板六——系统详细设计模板》 《信息化项目文档模板七——系统开发计划模板》 《信息化项目文档模板八——系统功能测试模板》 《信息化项目文档模板九——系统压力测试模板》 《信息化项目文档模板十——系统推广上线计划模板》 《信息化项目文档模板十一——系统用

商务合作|问题讨论|交流学习 请联系作者微信,加微信请务必注明来意,博客主页有联系方式 1713

一文详解mapstruct用法

随着业务的复杂,模块划分会越来越细。由于实体类存在于domain之中,并且domain通常要求不要被其他工程依赖,所以其他工程想获取实体类数据时就需要在各自工程写 dto,自定义dto可以根据自身业务需要映射相应的实体属性。所以需要进行转换映射,那么考虑到复杂对象的转换以及转换性能,mapstruct绝对是非常有效的手段。

WLKQNYJY_SHT的博客 3120

AI绘画与医疗可视化:用AI生成医学插图的实践

医疗可视化是医学教育、临床沟通和学术研究的核心工具。传统医学插图依赖手工绘制或专业3D建模,存在制作周期长、成本高、更新迭代慢等问题。随着深度学习技术的发展,AI绘画工具(如Stable Diffusion、DALL-E)展现出强大的图像生成能力,但医疗领域对插图的解剖准确性、标注规范性和语义完整性有极高要求,通用AI模型难以直接应用。本文聚焦AI技术与医疗领域的交叉创新,系统阐述如何通过数据预处理、模型定制化训练和后处理校验,构建符合医疗标准的插图生成系统。

大模型应用工坊 1788

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Mapstruct 基本用法

MapStruct 简介 在实际开发中我们在项目中经常要在 DTO、VO、DO、Entity 等实体之间进行转换,这种类型的框架也有很多,比如 Spring 框架中的 BeanUtils 工具类 ,但这个工具类是通过反射来实现的,性能相对低下且存在类型转换异常的问题,所以这个工具在有些公司是禁止使用的。下面简单说一下MapStruct,MapStruct 是一个代码生成器,它基于约定优于配置的方法极大地简化了Java bean类型之间映射的实现。与其他映射框架相比,MapStruct在编译时生成Bean映

weixin_43549350的博客 1431

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

MAPSTRUCT(@Mapper用法)简单介绍

简单介绍mapstruct的类型转换

balck_fly的博客 1万+

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

MapStruct用法和实践

MapStruct用法和实践

m0_50742275的博客 2000

MapStruct 超神进阶用法,让你的代码效率提升十倍!

前言MapStruct 是一个 Java 编译时注解处理框架,用来自动化将一种 Java Bean 对象映射成另一种类型的对象。该框架的主要目标是使开发人员在尽可能少的代码和最低的运行时间成本下实现属性映射。MapStruct 通过在编译时生成代码来实现这点,这与大多数其他 Java Bean 映射框架在运行时通过反射进行...

cnzzs的博客 773

mapstruct使用与进阶

本篇博客由浅入深的走进mapstruct这个非常好用的对象属性映射框架

qq_41463207的博客 4051

一文带你掌握Mapstruct用法

MapStruct用途 在我们项目中,我们经常要处理将DTO转换成VO,DTO转成Entity等各类对象相互转换,如果我们采用BeanUtils工具类的copyProperty进行转换,很容易出现转换性能低,类型转换错误等问题。 与其他转换工具相对,MapStruct具有以下优点: 通过使用普通方法调用而不是反射来快速执行 编译时类型安全性:只能映射相互映射的对象和属性,不能将订单实体意外映射到客...

青色橙子 1万+

MapStruct的使用详解与常见用法介绍

mapstruct在当前轻量级框架开发中的重点使用,@Named注解使用示例,@AfterMapping与@BeforeMapping注解的详细常见用法,在转换DTO时,与过去常用的beanUtil转换有高性能的转换优势,编译期自动生成的mapper实现类能够更加优雅的来实现各种隐式类型转换,以实现快速而又敏捷的开发,告别臃肿的手动get、set与类型的强转......

compellingMan的博客 1万+

mapstruct 用法详细介绍

mapstruct 用法 mapstruct 是什么 mapstruct一款是用于生成类型安全的bean映射类的Java注解处理器 JSR 269规范,只需要定义一个接口,配置字段映射规则,使用注解处理器,在代码编译阶段,生成对应的映射实现类,使用的是纯get/set方法,无反射调用,并且在编译阶段可校验错误 官网:https://mapstruct.org/documentation/stable/reference/html/#_apache_maven JSR 269规范:http://www.jcp

lujia_loney的博客 1989

MapStruct的基础用法详解

MapStruct 的一般理念是生成的代码看起来尽可能像您自己亲手编写的代码。特别是这意味着通过简单的 getter/setter 调用而不是反射或类似方法将值从源复制到目标。

yqw1401的博客 1万+
上一篇: Stack Overflow 2023 年开发者调查报告!
下一篇: 代码中 isEmpty 和 isBlank 的区别
架构文摘JGWZ
博客等级 码龄5年 8808粉丝 345原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值