MapStruct的一些常规用法
每天坚持写一篇原创文章。
使用过MapStruct之后,再也没用过BeanCopy来复制对象了。确实是非常好用的工具库。

MapStruct是一个代码生成器,简化了不同的Java Bean之间映射的处理,所以映射指的就是从一个实体变化成一个实体。例如我们在实际开发中,DAO层的实体和一些数据传输对象(DTO),大部分属性都是相同的,只有少部分的不同,通过mapStruct,可以让不同实体之间的转换变的简单。我们只需要按照约定的方式进行配置即可。
大家的命名都不一样,我个人是习惯把数据库的DO对象叫Entity实体。
返回前端的叫VO。
把Entity复制到VO并做一些操作或者转换,再返回前端,都会用到。
安装
1、引用
唯一需要注意的就是如果配合Lombok,需要在编译源码的插件上做好配置。
<properties>
<mapstruct.version>1.3.0.Final</mapstruct.version>
</properties>
<!-- MapStruct核心,包含了一些必要的注解-->
<dependencies>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${mapstruct.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven.compiler-plugin.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<compilerVersion>${java.version}</compilerVersion>
<fork>true</fork>
<encoding>${project.build.sourceEncoding}</encoding>
<verbose>true</verbose>
<annotationProcessorPaths>
<!-- 同时用Lombok,需要将Lombok放前面 -->
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
<!-- MapStruct编译,注解处理器,根据注解自动生成Mapper的实现 -->
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
2、定义转换接口
@Mapper
public interface OrderConvertor {
OrderConvertor INSTANCE = Mappers.getMapper(OrderConvertor.class);
@Mapping(source = "student.birthday", target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss") // 指定时间格式
@Mapping(target = "name", source = "student.name", defaultValue = "张三") //默认值
OrderVo toVo(OrderEntity order);
}
target表示目标属性名,source表示源属性名,一般在目标属性和源属性不同时使用,相同的属性名会自动进行映射。
MapStruct会自动生成对应接口的实现,并自动完成属性映射关系,List会自动进行批量处理。
3、使用时
@Service
public class OrderService {
public List<OrderVo> getOrderList() {
// 获取数据库数据
List<OrderEntity> result = selectOrderList();
// 参数转换
return OrderConvertor.INSTANCE.toVo(result);
}
}
下面是我常用的一些功能记录
1、添加为Spring的Component组件
@Mapper(componentModel = "spring")
2、List转换为String
类注解加上引用
@Mapper(imports = {Collectors.class, TelegramGroupEntity.class})
代码里面:使用表达式,转换为字符串
@Mapping(target = "groupStr", expression = "java(source.getBindGroups()!= null? source.getBindGroups().stream().map(TelegramGroupEntity::getName).collect(Collectors.joining(\", \")) : null)")
AcceptanceBankVo convert(AcceptanceBankEntity source);
直接转换List为换行的String
@Mapping(target = "groupStr", expression = "java(source.getBindGroups()!= null? source.getBindGroups().stream().map(TelegramGroupEntity::getName).collect(Collectors.joining(\"\\n\")) : null)")
直接调用方法
@Mapper(imports = {Collectors.class, TelegramGroupEntity.class, IndiaDateUtil.class})
public interface TransferBankConvert {
TransferBankConvert INSTANCE = Mappers.getMapper(TransferBankConvert.class);
@Mapping(target = "timeAgo", expression = "java(source.getLastActiveTime()!= null? IndiaDateUtil.getTimeAgo(source.getLastActiveTime(),\"Asia/Kolkata\") : null)")
TransferBankVo convert(TransferBankEntity source);
}
3、获取时间
@Mapping(target = "recordTime",expression = "java(new java.util.Date())")
4、空检查
@Mapper(nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS)
5、枚举映射String和string到枚举
int转枚举的value
@Mapper(imports = {AccptanceRoleTypeEnum.class}) // 加到类上引用进来
@Mapping(target = "roleText", expression = "java(AccptanceRoleTypeEnum.getItemValue(source.getRole()))")
枚举上加上:
/**
* 根据Value取描述
* @param value
* @return
*/
public static String getItemValue(Integer value) {
AccptanceRoleTypeEnum match = Stream.of(values()).filter(item -> item.value.equals(value)).findAny().orElse(null);
return match == null ? null : match.getDesc();
}
6、Fill同对象填充新对象,把source填充到target里面,和以前的beancopy一样的。
@BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE,
nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS)
@Mappings({
@Mapping(target = "id", ignore = true),
@Mapping(target = "createTime", ignore = true),
@Mapping(target = "updateTime", ignore = true)
})
void fill(TelegramGroupRoleEntity source, @MappingTarget TelegramGroupRoleEntity target);
要忽略空值填充
@BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
void update(DTO dto, @MappingTarget Bean bean);
7、Map提取,还是用表达式最简单
@Mappings({
@Mapping(expression = "java(mapConfig.getOrDefault(\"INPAY_RATES\",""))", target = "inpayRates"),
@Mapping(expression = "java(mapConfig.getOrDefault(\"AUTO_CREDIT\",""))", target = "autoCredit")
})
TelegramGroupWithConfigVo convert(TelegramGroupEntity entity);
8、空值判断
@Mapping(target = "targetField", expression = "java( sourceField == null || sourceField.isEmpty() ? null : sourceField )") 来将空字符串映射为 null
更多内容请关注我的公众号:青塬科技。
MapStruct的一些常规用法的更多相关文章
- GridView的常规用法
GridView控件在Asp.net中相当常用,以下是控件的解释,有些是常用的,有些是偶尔用到的,查找.使用.记录,仅此而已.(最后附带DropDownList控件) ASP.NET中GridView ...
- mapreduce的cleanUp和setUp的特殊用法(TopN问题)和常规用法
一:特殊用法 我们上来不讲普通用法,普通用法放到最后.我们来谈一谈特殊用法,了解这一用法,让你的mapreduce编程能力提高一个档次,毫不夸张!!!扯淡了,让我们进入正题: 我们知道reduce和m ...
- 【python】-matplotlib.pylab常规用法
目的: 了解matplotlib.pylab常规用法 示例 import matplotlib.pylab as pl x = range(10) y = [i * i for i in x] pl. ...
- MarkDown的常规用法
MarkDown的常规用法 标题 # 一级标题 ## 二级标题 ... ###### 六级标题 列表 第二级 - 和 空格 + 和 空额 * 和 空格 第三级 代码块 多行代码块 3个` 回车 单行代 ...
- C# 当中 LINQ 的常规用法(Lambda 方式)
仅以本篇博文记录 LINQ 相关操作的基本知识,原型参考自 MSDN 相关知识,中间加以自己的理解与 DEMO. 1. IEnuemrable<T>.Select() Select 方法比 ...
- Vuex 常规用法
背景 很多时候我们已经熟悉了框架的运用,但是有时候就是忘了怎么用 所以这里想记下大部分的框架使用方法,方便使用的时候拷贝 一.安装 npm 方式 npm install vuex --save yar ...
- iOS -Swift 3.0 -String(字符串常规用法)
// // ViewController.swift // Swift-String // // Created by luorende on 16/9/10. // Copyright © 2016 ...
- 关于strong、copy、weak、assign的常规用法
strong 对于普通的OC对象都是使用strong copy 对于 NSString,Block weak 用于OC对象,1.当出现循环强引用的时候,必须要保证一端是weak, 2 ...
- SimpleDateFormat 常规用法
public class SimpleDateFormat extends DateFormat SimpleDateFormat 是一个以国别敏感的方式格式化和分析数据的具体类. 它允许格式化 (d ...
- UITabbar的一些常规用法(总结)
往往系统自带的UITabbar 不能满足我们的样式或者颜色设计,所以需要调整UITabbar. 1.自定义UITabbar,也是我学到的第一种方式(简单暴力). 先记录一下思路: 首先,隐藏系统自带的 ...
随机推荐
- 震惊p div 标签 可以编辑高度随内容的编辑而发生变化
震惊p标签可以编辑高度随内容的编辑而发生变化### 1==>只可编辑,粘贴复制字段长度不正常 <p contenteditable="true" >这是一个可编辑 ...
- 分享一个项目:`learning_go_plan9_assembly`, 学习 golang plan9 汇编
作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 近期在学习 golang plan9 汇编,总算基本做到了 ...
- 每日一道Java面试题:Java是值传递还是引用传递?
写在开头 Java是值传递还是引用传递?这个问题几乎100%的出现在了各大主流Java面试题中,知识点很小,但很考验面试者对于Java运行的理解,今晚趁着生产投产的空子,过来小聊一下. 实参与形参 所 ...
- 携程Java三面面经,已拿 offer!!
分享一位读者投稿的携程校招 Java 岗位的面经. 下面是正文. 个人背景:双非本,机械专业转码. 携程在正式面试之前,会有一个性格测试(40分钟).性格测试之后,大概过一周进行笔试.笔试之后,会邮件 ...
- conda创建虚拟环境后文件夹中只有conda-meta文件夹,无法将环境添加到IDE中
1.问题描述:anaconda的envs的其中一个环境目录下,没有python.exe文件,只有conda-meta和scripts 平时创建虚拟环境都是: conda create -n test ...
- Visual Studio部署C++矩阵库Armadillo的方法
本文介绍在Visual Studio软件中配置C++环境下线性代数运算库Armadillo的方法. 首先,我们需要在Armadillo库官网下载其源代码,直接点击下图所示红色框内部分即可. ...
- 计算机网络|思维导图|自顶向下方法|MindMaps资料分享
前言 那么这里博主先安利一下一些干货满满的专栏啦! 手撕数据结构https://blog.csdn.net/yu_cblog/category_11490888.html?spm=1001.2014. ...
- 【C语言深度解剖】一篇搞懂结构体内存对齐【结构体的大小你会算了吗】
结构体内存对齐 大家好,我是西城s 文章目录 前言 引入 结构体内存对齐 `offsetof`宏的使用 为什么存在结构体内存对齐 修改默认对齐数 尾声 前言 作者: #西城s 这是我的主页:#西城s ...
- 洛谷P2241 统计方形 ,棋盘问题升级板,给出格子坐标中矩形以及正方形的计算方法
在做这道题之前我们先了解一下棋盘问题 棋盘问题 (qq.com) 对于棋盘问题,我们可以得出对于一个n*n的正方形方格阵如何求其包含的正方形个数 也就是数每个正方形的中间点,然后将其点排列 ...
- Build 和 Compile 区别