1.什么是MapStruct?

1.1 MapStruct

MapStruct官网

MapStruct是一个代码生成器,它基于约定优于配置的方法,极大地简化了Java bean类型之间映射的实现。生成的映射代码使用简单的方法调用,因此快速、类型安全且易于理解。
在装修房屋时,一些排线尽可能的走内线,注意会让房间显得更加整洁,美观。 MapStruct像一位代码的装修专家,简化Java Bean的转换。

1.2 添加依赖

 <dependency><groupId>org.mapstruct</groupId><artifactId>mapstruct</artifactId><version>1.3.1.Final</version></dependency>

2.应用场景

2.1 字段名称相等转换

2.1.1 单个对象转换

转换mapper

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
...@Mapper(componentModel = "spring")
public interface StudentMapper {/*** 转 responseDto* @param s* @return*/StudentResponseDTO entityToResponseDTO(Student s);
}

转换前Student实体类

{"age": 24,"className": "一年级五班","entranceTime": "2022-10-18","height": 180.0,"name": "我玩亚索我会C","weight": 140.0
}

转换后StudentResponseDTO

{"className": "一年级五班","name": "我玩亚索我会C"
}

2.1.2 集合转换

转换Mapper

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;@Mapper(componentModel = "spring")
public interface StudentMapper {/*** 转 responseDto list* @return*/List<StudentResponseDTO> listEntityToResponseListDto(List<Student> studentes);
}

转换前Student List集合

[{"age": 24,"className": "一年级五班","height": 180.0,"name": "我玩亚索我会C","weight": 140.0},{"age": 25,"className": "铃兰五班","height": 184.0,"name": "泷谷源治","weight": 130.0},{"age": 26,"className": "铃兰一班","height": 178.0,"name": "芹泽多摩雄","weight": 160.0},{"age": 24,"className": "铃兰火箭班","height": 175.0,"name": "辰川时生","weight": 120.0}
]

转换后 StudentResponseDTO 集合

[{"className": "一年级五班","name": "我玩亚索我会C"},{"className": "铃兰五班","name": "泷谷源治"},{"className": "铃兰一班","name": "芹泽多摩雄"},{"className": "铃兰火箭班","name": "辰川时生"}
]

2.2 字段不相等转换

2.2.1 单个对象转换

当被转换的对象中的属性名称和转换的对象中的属性名称不相等时,使用注解 @Mapping 来手动映射,target 表示目标,source表示源头,手动映射就是将source中的属性, 映射到target 中的属性。

转换Mapper

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
...@Mapper(componentModel = "spring")
public interface StudentMapper {/*** 转实体* @param dto* @return*/@Mapping(target = "name",source = "studentName")@Mapping(target = "className",source = "studentClassName")Student requestDTOToEntity(StudentRequestDTO dto);
}

转换前StudentRequestDTO

{"studentClassName": "E班","studentName": "林田惠"
}

转换后Student

{"className": "E班","name": "林田惠"
}

2.2.2 集合转换

字段不相等集合相互转换时,需要定义两个Mapper,一个是单个对象的转换,另一个是集合对象转换。

转换Mapper

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
...
import java.util.List;@Mapper(componentModel = "spring")
public interface StudentMapper {/*** 转 responseDto 字段不同* @param student* @return*/@Mapping(target = "studentName",source = "name")@Mapping(target = "studentClassName",source = "className")StudentInfoResponseDTO entityToResponseList(Student student);/*** 转 responseDto list 字段不同* @return*/List<StudentInfoResponseDTO> listEntityToResponseLists(List<Student> students);
}

转换前Student集合

[{"age": 24,"className": "一年级五班","height": 180.0,"name": "我玩亚索我会C","weight": 140.0},{"age": 25,"className": "铃兰五班","height": 184.0,"name": "泷谷源治","weight": 130.0},{"age": 26,"className": "铃兰一班","height": 178.0,"name": "芹泽多摩雄","weight": 160.0},{"age": 24,"className": "铃兰火箭班","height": 175.0,"name": "辰川时生","weight": 120.0}
]

转换后StudentInfoResponseDTO 集合

[{"studentClassName": "一年级五班","studentName": "我玩亚索我会C"},{"studentClassName": "铃兰五班","studentName": "泷谷源治"},{"studentClassName": "铃兰一班","studentName": "芹泽多摩雄"},{"studentClassName": "铃兰火箭班","studentName": "辰川时生"}
]

2.3 多个源

有些字段并不是对象中的属性,但是想赋值给转换后的对象,可以将该属性当做参数传入。

转换Mapper

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
...
import java.util.List;@Mapper(componentModel = "spring")
public interface StudentMapper {/*** 额外参数 转 实体类* @param dto* @param entranceTime 额外参数 入学时间* @return*/@Mapping(target = "name",source = "dto.studentName")@Mapping(target = "className",source = "dto.studentClassName")@Mapping(target = "entranceTime",source = "entranceTime")Student extraParamsToEntity(StudentRequestDTO dto,String entranceTime);
}

转换前StudentRequestDTO

{"studentClassName": "E班","studentName": "林田惠"
}

转换后Student

{"className": "E班","entranceTime": "2022-10-18","name": "林田惠"
}

注意:当mapper方法的参数有多个,手动映射时需要指定别名,如:@Mapping(target = "name",source = "dto.studentName")

2.4 默认值

想要给对象中的属性设置默认值使用defaultValue

import javax.xml.crypto.Data;
import java.time.LocalDateTime;@Mapper(componentModel = "spring")
public interface StudentMapper {/*** 默认参数 转 实体类* @param dto* @return*/@Mapping(target = "className",defaultValue = "五班")Student defaultToEntity(StudentRequestDTO dto);
}

2.5 数据类型映射

2.5.1 日期类型

指定日期格式。

import javax.xml.crypto.Data;
import java.time.LocalDateTime;@Mapper(componentModel = "spring")
public interface StudentMapper {/*** 日期类型映射 转 实体类* @param dto* @param entranceTime 入学时间* @return*/@Mapping(target = "entranceTime",dateFormat = "yyyy-MM-dd",source = "entranceTime")Student dateTypeToEntity(StudentRequestDTO dto,String entranceTime);
}

2.5.2 数字类型

保留两位小数。

import javax.xml.crypto.Data;
import java.time.LocalDateTime;@Mapper(componentModel = "spring")
public interface StudentMapper {/*** 数字类型映射 转 实体类* @param dto* @param entranceTime 入学时间* @return*/@Mapping(target = "tuition",numberFormat = "$#.00",source = "tuitionFee")Student dateTypeToEntity(StudentRequestDTO dto,String entranceTime);
}

2.6 表达式

entranceTime设置为当前时间
studentNo设置为随机数

@Mapper(componentModel = "spring",imports = {LocalDateTime.class, UUID.class})
public interface StudentMapper {/*** 表达式 转 实体类* @param dto* @return*/@Mapping(target = "entranceTime",expression = "java(LocalDateTime.now())")@Mapping(target = "studentNo",expression = "java(UUID.randomUUID().toString())")List<Student> expressionToEntities(List<StudentRequestDTO> dto);
}

3.注意事项

在使用MapStruct时,如果有映射的字段变更,一定要先clear清除编译文件,重新install编译。

MapStruct一个代码的装潢师相关推荐

  1. 如何看待不会写代码的架构师?

    在我作为程序员,软件工程师从业的十几年见过各种架构师,既有深耕各种技术框架,对各类框架的性能,局限,应用场景如数家珍的技术架构师.也有各类业务门清儿,擅长制作PPT,VISIO,AXURE这类以描述, ...

  2. 成为一个高级Java架构师所需要具备那些技能呢?

    成为java架构师所需要具备那些技能? 所谓架构师,思考的是全局的东西,是如何组织你的系统,以达到业务要求,性能要求,具备可扩展性(scalability),可拓展性(extendability),前 ...

  3. python默认的一个代码缩进是几个空格_python缩进长度是否统一

    Python 对代码的缩进要求非常严格,同一个级别代码块的缩进量必须一样,否则解释器会报 SyntaxError 异常错误. 在 Python 中,对于类定义.函数定义.流程控制语句.异常处理语句等, ...

  4. 推荐一个代码自动完成的工具AutoCode

    本文转载:http://www.cnblogs.com/xiaoxiangfeizi/archive/2012/07/24/2605884.html 最近发现了一个代码自动完成工具AutoCode,特 ...

  5. 为修复一个代码执行安全漏洞,TensorFlow决定不再支持YAML

    TensorFlow是谷歌开发的基于Python的机器学习和人工智能项目.为修复一个代码执行安全漏洞,TensorFlow决定不再支持YAML.YAML(Yet Another Markup Lang ...

  6. 我对架构师的理解(如何成为一个合格的架构师)

    我对架构师的理解(如何成为一个合格的架构师) 引子: 在讨论架构之前,我们先上道菜,青椒土豆肉丝,这道小菜味道还是不错的,自私点了,不考虑您是否喜欢,今天就上它了. 准备原材料:食用油.青椒.土豆.肉 ...

  7. 一个代码托管平台居然公开拒招中国人,谁给了你歧视中国程序员的勇气?

    今天,有不少人吃了一个"代码界"的瓜. 由谷歌投资的全球第二大开源代码托管平台GitLab(第一大是GitHub)在其官网上发布了一项声明,称他们决定为有权访问客户数据的团队成员启 ...

  8. python 代码行数统计工具_使用Python设计一个代码统计工具

    问题 设计一个程序,用于统计一个项目中的代码行数,包括文件个数,代码行数,注释行数,空行行数.尽量设计灵活一点可以通过输入不同参数来统计不同语言的项目,例如: # type用于指定文件类型 pytho ...

  9. 【人工智能AI】AI写作:《怎样成为一个优秀的架构师》

    怎样成为一个优秀的架构师?分别从技术.业务.项目管理等方面详细说明,细化到3级目录,不少于3000字.用markdown格式. 文章目录 AI写作:<怎样成为一个优秀的架构师> 架构师的技 ...

  10. 怎样才能把一个代码变成软件成品?一个初学者的困惑,我们写的代码都只能是解决一些数学问题而已。怎么把它变成一个软件。

    小弟疑惑... 怎样才能把一个代码变成软件成品?一个初学者的困惑,我们写的代码都只能是解决一些数学问题而已.怎么把它变成一个软件. 大神月... 对于您这个问题,当初也是我的好奇之处啊!其实你学好一门 ...

最新文章

  1. springboot多模块打包指定子模块环境配置文件
  2. VMware 主机基板管理控制器的状态
  3. 【Groovy】自定义 Xml 生成器 BuilderSupport ( setParent 方法中设置父节点与子节点关系 )
  4. CMS GC:CMS 废弃了,该怎么办呢?
  5. vuejs之【router-link】大全(二)
  6. 快放弃你的管家软件吧! Part 2 强制删除
  7. C# WPF MVVM模式Prism框架下事件发布与订阅
  8. 购物车的功能——CSS源码
  9. 大数据在智慧城市中重要的作用
  10. RNA在相分离中的作用RNA buffers the phase separation behavior of prion-like RNA- binding proteins
  11. 价值过亿的架构师面试试题大全和答案、架构大全、代码大全
  12. Springboot使用Curator 集成zk
  13. iOS SwiftUI ☞ UIKit框架的封装使用
  14. java 四边形_java求教,编写一个四边形的类与子类
  15. Unity3dC#分布式游戏服务器ET框架介绍-组件式设计(转)
  16. 这是我见过最牛逼的滑动加载前端框架
  17. AI前沿论坛会议—文字智能和游戏智能总结篇
  18. ggplot画世界地图
  19. 【C++】深度剖析string类的底层结构及其模拟实现
  20. 中国风机过滤机组(ffu)市场发展现状与营销策略分析报告2022-2027年

热门文章

  1. H3C路由器-内/外网用户通过公网IP访问内部服务器
  2. 提高芯片在线烧录稳定性的6个方法
  3. 苹果可能会失去中国的iPad商标
  4. Oracle EBS使用adpatch工具打patch过程【Z】
  5. Python爬取豆瓣top榜电影
  6. Python进行各项统计检验
  7. 读取 RV1126 CPU温度 NPU CPU频率
  8. 小米路由器3G刷入OpenWrt
  9. [转载]大数据入门 - 董飞
  10. Tumblr营销大法(三)