Java实体映射工具MapStruct使用详解

2023-10-27

1.序

通常在后端开发中经常不直接返回实体Entity类,经过处理转换返回前端,前端提交过来的对象也需要经过转换Entity实体才做存储;通常使用的BeanUtils.copyProperties方法也比较粗暴,不仅效率低下(使用反射)而且仅映射相同名的属性,多数情况下还需要手动编写对应的转换方法实现。
插件MapStruct以接口方法结合注解优雅实现对象转换,MapStruct生成器生成代码以更贴近原生的Setter、Getter方法处理属性映射更为高效。

2.简单用例

实体对象User

@Data
@AllArgsConstructor
public class User {
    private int id;
    private String name;
    private int age;
    private String address;
}

转换对象UserVO

@Data
public class UserVO {
    private String userName;
    private int age;
}

转换接口

@Mapper
public interface UserConvert {
    UserConvert INSTANCE = Mappers.getMapper(UserConvert.class);
    @Mapping(source = "name", target = "userName")
    UserVO toVO(User entity);
}

使用示例

@Test
public void contextLoads() {
    User user = new User(0, "Tester", 1, "上海市徐汇区");
    UserVO userVO = UserConvert.INSTANCE.toVO(user);
}

3.使用详解

1)关于接口注解@Mapper几种属性用法详解

uses 使用其他手动编写的或者其他Mapper接口覆写相关的转换方法,不能循环引用

@Mapper(uses=DateMapper.class)

imports 引用相关类,允许通过mapping.expression()mapping.defaultExpression()直接使用这些类型

@Mapper(imports = DateUtil.class)
public interface UserConvert {
    UserConvert INSTANCE = Mappers.getMapper(UserConvert.class);
    @Mappings({
            @Mapping(source = "name", target = "userName"),
            // 以指定方法转换属性,这里如果不使用imports,则需要写全引用类包路径
            @Mapping(target = "birthday", expression = "java(DateUtil.formatDate(entity.getBirthday()))")
    })
    UserVO toVO(User entity);
}

unmappedSourcePolicyunmappedTargetPolicy 针对源类型/目标类型中未映射属性的反馈策略
typeConversionPolicy 针对有损转换的反馈策略,例如Long转Integer
反馈策略主要有三种:IGNORE,默认值,忽略未映射的字段。WARN,警告。ERROR,报错

@Mapper(unmappedSourcePolicy = ReportingPolicy.ERROR)

componentModel 指定生成映射器实例的模式,主要有四种:
default,不主动生成实例,通常以Mappers.getMapper(Class)实例化。
cdi,以CDI标准实例化映射器,使用@Inject注入相关实例,
spring,Spring Bean方式实例化,
jsr330,jsr330标准实例化

@Mapper(componentModel = "spring")
public interface UserConvert {
    @Mapping(source = "name", target = "userName")
    UserVO toVO(User entity);
}
@Autowired
private UserConvert userConvert;

implementationName 指定实现类名称,映射生成器接口会自动生成实现类<CLASS_NAME>Impl,使用此属性可避免类冲突
implementationPackage 指定实现类包路径

config 指定配置类,由指定的@MapperConfig配置类,config导入相关配置
配置类

@MapperConfig(
        uses = DateUtil.class,
        unmappedSourcePolicy = ReportingPolicy.WARN
)
public interface UserConfig {
}

导入配置类

@Mapper(componentModel = "spring", config = UserConfig.class)

collectionMappingStrategy 集合映射策略,这里注意集合映射时,如果集合中的类型已有对应转换方法,集合转换时会优先使用

@Mappings({
        @Mapping(source = "name", target = "userName"),
        @Mapping(target = "birthday", expression = "java(DateUtil.formatDate(entity.getBirthday()))")
})
UserVO toVO(User entity);
List<UserVO> collectionCvt(List<User> entities);

GENERATED CODE 生成器生成代码

public List<UserVO> collectionCvt(List<User> entities) {
    if (entities == null) {
        return null;
    } else {
        List<UserVO> list = new ArrayList(entities.size());
        Iterator var3 = entities.iterator();

        while(var3.hasNext()) {
            User user = (User)var3.next();
            // 集合转换时优先使用了已定义的toVO方法
            list.add(this.toVO(user));
        }

        return list;
    }
}

nullValueMappingStrategy null作为源值映射策略;RETURN_NULL默认返回null, RETURN_DEFAULT返回默认值,对于对象会通过构造器自动构造对象返回,集合会返回空集合

当值为RETURN_DEFAULT时,如果映射规则中包含Mapping.expression、Mapping.constant必须手动判空处理,否则NPE

@MapperConfig(nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT)

NullValuePropertyMappingStrategy null作为源属性映射策略;SET_TO_NULL默认返回null,SET_TO_DEFAULT返回默认值,IGNORE 忽略该值,以目标对象已存在的值为准

MappingInheritanceStrategy 继承方法级映射配置策略:EXPLICIT 显示使用InheritConfiguration生效。AUTO_INHERIT_FROM_CONFIG 自动继承正向转换的配置。AUTO_INHERIT_REVERSE_FROM_CONFIG 自动继承反向转换的配置。AUTO_INHERIT_ALL_FROM_CONFIG 都继承

@MapperConfig(
        mappingInheritanceStrategy = MappingInheritanceStrategy.EXPLICIT
)
@InheritConfiguration
void cvtVO(User entity, @MappingTarget UserVO vo);

nullValueCheckStrategy 空值监测策略

2) 其他方法级别注解

@InheritInverseConfiguration 反向转换时继承映射规则

@Mapping 配置类型属性的映射规则;
dateFormat 格式化日期

@Mapping(target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss")

numberFormat 数字格式化

@Mapping(target = "price", numberFormat = "$#.00")

constant 常量

@Mapping(target = "age", constant = "0")
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java实体映射工具MapStruct使用详解 的相关文章

  • 按键时关闭 ModalWindow

    我希望能够在用户按下某个键 在我的例子中是 ESC 时关闭 ModalWindow 我有一个用于按键的 Javascript 侦听器 它调用取消按钮 ID 的单击事件 jQuery modalWindowInfo closeButtonId
  • Java中有没有一种方法可以通过名称实例化一个类?

    我正在寻找问题 从字符串名称实例化一个类 https stackoverflow com questions 9854900 instantiate an class from its string name它描述了如何在有名称的情况下实例
  • 如何将本机库链接到 IntelliJ 中的 jar?

    我正在尝试在 IntelliJ 中设置 OpenCV 但是我一直在弄清楚如何告诉 IntelliJ 在哪里可以找到本机库位置 在 Eclipse 中 添加 jar 后 您可以在 Build Config 屏幕中设置 Native 库的位置
  • 日期语句之间的 JPQL SELECT [关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我想将此 SQL 语句转换为等效的 JPQL SELECT FROM events WHERE events date BETWE
  • Junit:如何测试从属性文件读取属性的方法

    嗨 我有课ReadProperty其中有一个方法ReadPropertyFile返回类型的Myclass从属性文件读取参数值并返回Myclass目的 我需要帮助来测试ReadPropertyFile方法与JUnit 如果可能的话使用模拟文件
  • .properties 中的通配符

    是否存在任何方法 我可以将通配符添加到属性文件中 并且具有所有含义 例如a b c d lalalala 或为所有以结尾的内容设置一个正则表达式a b c anything 普通的 Java 属性文件无法处理这个问题 不 请记住 它实际上是
  • 为 java 游戏创建交互式 GUI

    大家好 我正在创建一个类似于 java 中的 farmville 的游戏 我只是想知道如何实现用户通常单击以与游戏客户端交互的交互式对象 按钮 我不想使用 swing 库 通用 Windows 看起来像对象 我想为我的按钮导入自定义图像 并
  • 如何使用assertEquals 和 Epsilon 在 JUnit 中断言两个双精度数?

    不推荐使用双打的assertEquals 我发现应该使用带有Epsilon的形式 这是因为双打不可能100 严格 但无论如何我需要比较两个双打 预期结果和实际结果 但我不知道该怎么做 目前我的测试如下 Test public void te
  • HSQL - 识别打开连接的数量

    我正在使用嵌入式 HSQL 数据库服务器 有什么方法可以识别活动打开连接的数量吗 Yes SELECT COUNT FROM INFORMATION SCHEMA SYSTEM SESSIONS
  • 如何在 Spring 中禁用使用 @Component 注释创建 bean?

    我的项目中有一些用于重构逻辑的通用接口 它看起来大约是这样的 public interface RefactorAwareEntryPoint default boolean doRefactor if EventLogService wa
  • jQuery AJAX 调用 Java 方法

    使用 jQuery AJAX 我们可以调用特定的 JAVA 方法 例如从 Action 类 该 Java 方法返回的数据将用于填充一些 HTML 代码 请告诉我是否可以使用 jQuery 轻松完成此操作 就像在 DWR 中一样 此外 对于
  • Java 公历日历更改时区

    我正在尝试设置 HOUR OF DAY 字段并更改 GregorianCalendar 日期对象的时区 GregorianCalendar date new GregorianCalendar TimeZone getTimeZone GM
  • 在 junit 测试中获取 javax.lang.model.element.Element 类

    我想测试我的实用程序类 ElementUtils 但我不知道如何将类作为元素获取 在 AnnotationProcessors 中 我使用以下代码获取元素 Set
  • volatile、final 和synchronized 安全发布的区别

    给定一个带有变量 x 的 A 类 变量 x 在类构造函数中设置 A x 77 我们想将 x 发布到其他线程 考虑以下 3 种变量 x 线程安全 发布的情况 1 x is final 2 x is volatile 3 x 设定为同步块 sy
  • 尝试将 Web 服务部署到 TomEE 时出现“找不到...的 appInfo”

    我有一个非常简单的项目 用于培训目的 它是一个 RESTful Web 服务 我使用 js css 和 html 创建了一个客户端 我正在尝试将该服务部署到 TomEE 这是我尝试部署时遇到的错误 我在这里做错了什么 刚刚遇到这个问题 我曾
  • java for windows 中的文件图标叠加

    我正在尝试像 Tortoise SVN 或 Dropbox 一样在文件和文件夹上实现图标叠加 我在网上查了很多资料 但没有找到Java的解决方案 Can anyone help me with this 很抱歉确认您的担忧 但这无法在 Ja
  • Eclipse 启动时崩溃;退出代码=13

    I am trying to work with Eclipse Helios on my x64 machine Im pretty sure now that this problem could occur with any ecli
  • 我如何在java中读取二进制数据文件

    因此 我正在为学校做一个项目 我需要读取二进制数据文件并使用它来生成角色的统计数据 例如力量和智慧 它的设置是让前 8 位组成一个统计数据 我想知道执行此操作的实际语法是什么 是不是就像读文本文件一样 这样 File file new Fi
  • CamcorderProfile.videoCodec 返回错误值

    根据docs https developer android com reference android media CamcorderProfile html 您可以使用CamcorderProfile获取设备默认视频编解码格式 然后将其
  • Java中super关键字的范围和使用

    为什么无法使用 super 关键字访问父类变量 使用以下代码 输出为 feline cougar c c class Feline public String type f public Feline System out print fe

随机推荐

  • Unity打开项目之Hold on,之第一次打开25G的文件夹,之我的自闭之旅

    环境 Unity2017 4 36 VS2019 Windows10 介绍 使用Unity打开一个进25G的项目 文件中包含各个平台的代码 第一次打开花费了进4个小时 关闭后在次打开花费了近 按理说只有第一次加载才会需要很长时间 第二次相对
  • Stata学习笔记

    今天学习的视频是 Stata入门 外部命令安装 哔哩哔哩 bilibili up主 silencedream Stata设置 如何快速安装3000 外部命令 连玉君老师PLUS文件 哔哩哔哩 bilibili up主 小志小视界 外部命令安
  • Matlab --- 如何用matlab在三维坐标系中画一个三维向量

    用MATLAB画三维向量 前两天 我在写Gram Schmidt正交化的文章时 想到最好用matlab把还没有经过正交化计算的原始向量 和已经经过正交化处理后的正交基 在三维坐标系中 用图像的方式表示出来 这样可以更加直观的看到向量与向量之
  • AC-DC--单相桥式全控整流电流源

    单相整流电路中应用较多的是单相桥式全控整流电路 带电阻负载的工作情况 原理图 波形图 在单相桥式全控整流电路中 晶闸管VT1 和VT4 组成一对桥臂 VT2和VT3 组成另一对桥臂 工作原理 在uz正半周 即 a点电位高于b点电位 若4个晶
  • 用户画像标签体系——从零开始搭建实时用户画像(三)

    用户画像标签体系 用户画像的核心在于给用户 打标签 每一个标签通常是人为规定的特征标识 用高度精炼的特征描述一类人 例如年龄 性别 兴趣偏好等 不同的标签通过结构化的数据体系整合 就可与组合出不同的用户画像 梳理标签体系是实现用户画像过程中
  • 如何通过内网穿透实现外部网络对Spring Boot服务端接口的HTTP监听和调试?

    文章目录 前言 1 本地环境搭建 1 1 环境参数 1 2 搭建springboot服务项目 2 内网穿透 2 1 安装配置cpolar内网穿透 2 1 1 windows系统 2 1 2 linux系统 2 2 创建隧道映射本地端口 2
  • JS获取系统时间

    网页通过JavaScript获取系统日期 时间的操作是比较常规的操作 我这里将自己使用过的方法小结一下 方便自己回顾或参考 目录 一 实现非常简单 第一步实例化 第二步获取值 二 参考实例 1 无格式要求简单获取 2 自定义格式获取 3 闰
  • 实现vue自定义指令v-loading

    1 创建文件 在 loading文件夹下创建3个文件 index js loading vue 和 loading js index js文件用来暴露安装插件接口 这个下面会有说明 有了 Vue directive这个方法就可以在页面中使用
  • Springboot获取IOC容器的方式

    1 前言 大家好 我是孤焰 最近我在制作日志审计功能时发现不知道怎样获取到Springboot项目中的IOC容器 经过摸索 最终解决了这个问题 现在把解决方式和大家分享一下 2 Springboot项目中获取IOC容器的方式 在Spring
  • go中如何处理error

    0 前言 go 中的异常处理和其他语言大不相同 像 Java C python 等语言都是通过抛出 Exception 来处理异常 而 go 是通过返回 error 来判定异常 并进行处理 在 go 中有 panic 的机制 但 panic
  • IDEA中使用vue 报 Namespace 'xxx' is not bound的解决办法

    IDE 问题编辑页中v on指令标红并提示 Namespace v on is not bound 解决办法 file Settings下 点ok后标红提示的问题解决 此方法是 Namespace xxx is not bound 通用解决
  • 阿里云RDS如何进行账号及数据库管理?

    本文说说如何管理RDS实例 进入控制台 选中RDS 在列表中选择我们需要管理的地域 并且找到我们需要管理的实例 首先建立一个数据库 点击数据库管理 点击创建数据库 输入数据库名 确定
  • [工具使用]WhatWeb

    网站指纹识别工具WhatWeb WhatWeb简介 用法 10小点 因为想要面对一个新的开始 一个人必须有梦想 有希望 有对未来的憧憬 如果没有这些 就不叫新的开始 而叫逃亡 玛丽亚 杜埃尼亚斯 WhatWeb简介 web指纹扫描主要用于对
  • modbus tcp报文解析_Modbus协议详解

    Modbus概述 Modbus通信协议由Modicon公司 现已经为施耐德公司并购 成为其旗下的子品牌 于1979年发明的 是全球最早用于工业现场的总线规约 由于其免费公开发行 使用该协议的厂家无需缴纳任何费用 Modbus通信协议采用的是
  • 如何共享服务器主机文件,服务器主机如何做文件共享

    服务器主机如何做文件共享 内容精选 换一换 云堡垒机支持文件传输功能 以及审计传输的文件 Linux主机和Windows主机的文件传输方式有所区别 Linux主机上传 下载文件 可选择Web运维和FTP SFTP客户端运维两种方式 Web运
  • C#学习笔记-C#的类及其成员

    类 是面向对象语言的的一个基本特征 它是一种数据结构 类可以理解为将现实生活中的食物进行抽象的结果 比如创建一个person的类 人有身高体重年龄的基本属性 而类的实例化是指将类具体化 比如刚刚创建的一个person的类 将他实例化之后 就
  • 【Vue】关于CSS样式绑定整理

    因突发奇想设计一款组件 需要根据属性动态绑定样式 故而整理一些Vue的动态绑定样式方法 传参绑定类似 不做过多叙述 仅供参考 方式一 直接在元素上绑定具体样式 方式二 定义属性对象 绑定到style 可以在style中使用定义的变量 方式二
  • Linux格式化命令

    如果我们购买一个新的虚拟主机空间或者要更改操作程序 会经常使用到磁盘格式化来清空以前的数据 磁盘格式化的方法很多 我们常用的是NTFS和linux格式化命令两种方法来格式化磁盘 我们讲解一下linux格式化命令的详情 linux格式化磁盘命
  • 自学中走出的大三学生面临就业选择

    来信 贺老师您好 这是我第二次向您请教问题了 非常感谢您上次给我的建议 注 上次来信见http blog csdn net sxhelijian article details 7760011 如邮件主题所述 我是一个即将大四的学生 我学的
  • Java实体映射工具MapStruct使用详解

    1 序 通常在后端开发中经常不直接返回实体Entity类 经过处理转换返回前端 前端提交过来的对象也需要经过转换Entity实体才做存储 通常使用的BeanUtils copyProperties方法也比较粗暴 不仅效率低下 使用反射 而且