当前位置:网站首页>MapStruct入门使用
MapStruct入门使用
2022-08-08 12:48:00 【林凡尘coding】
背景
在实际的项目开发中会大量的使用POJO作为数据载体,通常有如下的:
| 实体名 | 实体含义 | 说明 |
|---|---|---|
| DO | Data Object | 与数据库表结构一一对应,通过DAO层向上传输数据源对象 |
| DTO | Data Transfer Object | 数据传输对象,Service或Manager向外传输的对象 |
| BO | Business Object | 业务对象,由Service层输出的封装业务逻辑的对象 |
| VO | View Object | 显示层对象,通常是 Web 向模板渲染引擎层传输的对象 |
- Spring BeanUtils
- Apache BeanUtils
- Orika的MapperFacade和MapperFactory
- MapStruct
可以选择MapStruct,功能十分强大,而且很灵活,可以满足我们需要的各种需求。
入门案例
Maven项目引入
只需要在pom.xml文件中加入以下依赖即可:
...
<properties>
<java.version>1.8</java.version>
<mapstruct.version>1.3.1.Final</mapstruct.version>
</properties>
...
<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>3.8.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
...
源对象

CarDO
package com.linfanchen.springboot.lab.mapstruct.domain;
public class CarDO {
/** * 主键ID */
private Integer id;
/** * 名称 */
private String name;
/** * 品牌 */
private String brand;
/** * 车价 */
private Integer price;
/** * 轮胎属性 */
private TyreDO tyreDO;
/** * 汽车图片 */
private String images;
public String getImages() {
return images;
}
public void setImages(String images) {
this.images = images;
}
public TyreDO getTyreDO() {
return tyreDO;
}
public void setTyreDO(TyreDO tyreDO) {
this.tyreDO = tyreDO;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public Integer getPrice() {
return price;
}
public void setPrice(Integer price) {
this.price = price;
}
}
TyreDO
package com.linfanchen.springboot.lab.mapstruct.domain;
/** * 轮胎 */
public class TyreDO {
/** * 主键ID */
private Integer id;
/** * 轮胎名称 */
private String name;
/** * 轮胎尺寸 */
private Integer size;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getSize() {
return size;
}
public void setSize(Integer size) {
this.size = size;
}
}
目标对象
CarBO
package com.linfanchen.springboot.lab.mapstruct.bo;
import com.linfanchen.springboot.lab.mapstruct.domain.TyreDO;
import java.util.List;
/** * 汽车业务对象 */
public class CarBO {
/** * 主键ID */
private Integer id;
/** * 名称 */
private String name;
/** * 品牌 */
private String brand;
/** * 车价 */
private Integer price;
/** * 轮胎属性 */
private TyreDO tyreDO;
/** * 汽车图片 */
private String images;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public Integer getPrice() {
return price;
}
public void setPrice(Integer price) {
this.price = price;
}
public TyreDO getTyreDO() {
return tyreDO;
}
public void setTyreDO(TyreDO tyreDO) {
this.tyreDO = tyreDO;
}
public String getImages() {
return images;
}
public void setImages(String images) {
this.images = images;
}
}
CarDetailBO
package com.linfanchen.springboot.lab.mapstruct.bo;
import com.linfanchen.springboot.lab.mapstruct.domain.TyreDO;
import java.util.List;
/** * 汽车业务对象 */
public class CarDetailBO {
/** * 主键ID */
private Integer carId;
/** * 名称 */
private String carName;
/** * 品牌 */
private String carBrand;
/** * 车价 */
private Integer price;
/** * 轮胎属性 */
private TyreDO tyreDetail;
/** * 汽车图片 */
private List<String> images;
public Integer getCarId() {
return carId;
}
public void setCarId(Integer carId) {
this.carId = carId;
}
public String getCarName() {
return carName;
}
public void setCarName(String carName) {
this.carName = carName;
}
public String getCarBrand() {
return carBrand;
}
public void setCarBrand(String carBrand) {
this.carBrand = carBrand;
}
public Integer getPrice() {
return price;
}
public void setPrice(Integer price) {
this.price = price;
}
public TyreDO getTyreDetail() {
return tyreDetail;
}
public void setTyreDetail(TyreDO tyreDetail) {
this.tyreDetail = tyreDetail;
}
public List<String> getImages() {
return images;
}
public void setImages(List<String> images) {
this.images = images;
}
}
转换器 CarConvert
说明:
- INSTANCE 是MapStruct为我们提供的映射工厂,指定接口类型后自动帮我们创建接口的实现,且保证是线程安全的单例,无需自己手动创建。
package com.linfanchen.springboot.lab.mapstruct.convert;
import com.linfanchen.springboot.lab.mapstruct.bo.CarBO;
import com.linfanchen.springboot.lab.mapstruct.bo.CarDetailBO;
import com.linfanchen.springboot.lab.mapstruct.domain.CarDO;
import org.apache.commons.lang3.StringUtils;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.Named;
import org.mapstruct.factory.Mappers;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/** * 转换类 */
@Mapper
public interface CarConvert {
CarConvert INSTANCE = Mappers.getMapper(CarConvert.class);
/** * 来源和目标类的直接转换 */
CarBO convert(CarDO carDO);
/** * 添加字段处理和映射关系后的转换 */
@Mappings({
@Mapping(source = "id", target = "carId"),
@Mapping(source = "name", target = "carName"),
@Mapping(source = "brand", target = "carBrand"),
@Mapping(source = "tyreDO.id", target = "tyreDetail.id"),
@Mapping(source = "tyreDO.name", target = "tyreDetail.name"),
@Mapping(source = "tyreDO.size", target = "tyreDetail.size"),
@Mapping(source = "images", target = "images", qualifiedByName = "convertImagesStrToList")
})
CarDetailBO convertDetail(CarDO carDO);
@Named("convertImagesStrToList")
default List<String> convertImagesStrToList(String images) {
String[] splitArr = org.springframework.util.StringUtils.split(images, ",");
return new ArrayList<>(Arrays.asList(splitArr));
}
}
使用 CarTest
package com.linfanchen.springboot.lab.mapstruct;
import com.linfanchen.springboot.lab.mapstruct.bo.CarBO;
import com.linfanchen.springboot.lab.mapstruct.bo.CarDetailBO;
import com.linfanchen.springboot.lab.mapstruct.convert.CarConvert;
import com.linfanchen.springboot.lab.mapstruct.domain.CarDO;
import com.linfanchen.springboot.lab.mapstruct.domain.TyreDO;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
@RunWith(SpringRunner.class)
@SpringBootTest
public class CarTest {
@Test
public void test() {
// 创建轮胎对象
TyreDO tyreDO = new TyreDO();
tyreDO.setId(888);
tyreDO.setName("米其林245/45R19");
tyreDO.setSize(19);
// 汽车图片地址,通过半角逗号分隔的http地址
List<String> imageList = new ArrayList<>();
imageList.add("https://www.bmw.com.cn/image.1601043751651.jpg");
imageList.add("https://www.bmw.com.cn/image.1623295725814.jpg");
imageList.add("https://www.bmw.com.cn/image.1611042489480.jpg");
String imageStr = imageList.stream().map(String::valueOf).collect(Collectors.joining(","));
// 创建汽车对象
CarDO carDO = new CarDO();
carDO.setId(123);
carDO.setBrand("BMW");
carDO.setName("宝马530Li行政版");
carDO.setPrice(540000);
carDO.setTyreDO(tyreDO);
carDO.setImages(imageStr);
// 直接的数据拷贝
CarBO carBO = CarConvert.INSTANCE.convert(carDO);
System.out.println(carBO.getImages());
System.out.println(carBO.getBrand());
System.out.println(carBO.getName());
System.out.println(carBO.getTyreDO());
// 带数据转换的拷贝
CarDetailBO carDetailBO = CarConvert.INSTANCE.convertDetail(carDO);
System.out.println(carDetailBO.getImages());
System.out.println(carDetailBO.getTyreDetail().getName());
}
}
总结
在需要进行对象的转换的时候,我们可以使用MapStruct进行各种灵活的转换,最终得到我们想要的数据。
参考文档:
边栏推荐
- ctfshow 七夕杯(复现)
- R语言ggplot2可视化:基于aes函数中的fill参数和shape参数自定义绘制分组折线图并添加数据点(散点)、设置可视化图像的主题为theme_gray
- 爱可可AI前沿推介(8.8)
- 2022-08-04
- Study: Toxic PFAS chemicals make rainwater unsafe to drink around the world
- SQL INSERT INTO and INSERT INTO the SELECT statement
- 三个点语法和DOM观察者
- 期货开户的交易通道和后续服务
- (7) FlinkSQL kafka data written to the mysql way 2
- 将小部分源码设计精髓带入到开发中来(工厂模式、适配器模式、抽象类、监听器)
猜你喜欢

作为一个年薪50W阿里P7架构师的必备知识:并发+JVM+多线程+Netty+MySQL

SAP数据迁移需要多久?

phpstyle安装管理mysql

看到这个应用上下线方式,不禁感叹:优雅,太优雅了!

建材业深陷数字化困局,B2B协同系统标准化交易流程,解决企业交易网络化难题

The programmer essential VS debugging technique
![[界面开发]DevExpress WinForms流程图控件——XtraDiagrams组件入门指南](/img/0f/ef24101bebfea90e457a92e3017a3e.png)
[界面开发]DevExpress WinForms流程图控件——XtraDiagrams组件入门指南

【AI系统前沿动态第45期】Hinton:深度学习的下一个大事件;一块GPU训练TB级推荐模型不是梦;AI-GPU显存优化发展史

指针和数组笔试题解析

SQL实例 - 胜平负
随机推荐
别再到处乱放配置文件了!试试我司使用 7 年的这套解决方案,稳的一秕
[C language] Detailed explanation of custom types: structure, enumeration, union
深度剖析-class的几个对象(utlis,component)-瀑布流-懒加载(概念,作用,原理,实现步骤)
移位运算、位运算、逻辑运算相关知识点及笔试题
Pointer and array written test questions analysis
C语言的三个经典题目:三步翻转法、杨氏矩阵、辗转相除法
JPA之使用复合主键
SAP数据迁移需要多久?
硬盘数据恢复工具
changes not staged for commit 解决办法
PHP中使用XML-RPC构造Web Service简单入门
老手也常误用!详解 Go channel 内存泄漏问题
R语言ggplot2可视化:使用ggpubr包的ggbarplot函数可视化堆叠的柱状图(stacked bar plot)、palette参数自定义不同水平柱状图边框以及填充的颜色
AfterEffect插件-图层排序-js脚本开发-AE插件
Background, History and Lessons of Transfer Learning
(4)FlinkSQL将socket数据写入到mysql方式一
"Huashu Cup" modeling learning (Matlab)
家电行业趋势:2022从三方面把握家电产品升级方向
MySQL:锁机制 |表级锁、行级锁 | 排它锁、共享锁 | 间隙锁
Server Configuration - Install Redis on Linux System