Mapstruct Plus 是 Mapstruct 的增强工具,在 Mapstruct 的基础上,实现了自动生成 Mapper 接口的功能,并强化了部分功能,使 Java 类型转换更加便捷、优雅。
和 Mapstruct 一样,本质上都是一个基于 JSR 269 的 Java 注释处理器,因此可以由 Maven 、Gradle 、Ant 等来构建触发。
Mapstruct Plus 内嵌 Mapstruct ,和 Mapstruct 完全兼容,如果之前已经使用 Mapstruct ,可以无缝替换依赖。
假设有两个类 UserDto 和 User ,分别表示数据层对象和业务层对象:
UserDto
public class UserDto {
private String username;
private int age;
private boolean young;
// getter 、setter 、toString 、equals 、hashCode
}
User
public class User {
private String username;
private int age;
private boolean young;
// getter 、setter 、toString 、equals 、hashCode
}
添加依赖: 引入 mapstruct-plus-spring-boot-starter 依赖:
<properties>
<mapstruct-plus.version>1.3.6</mapstruct-plus.version>
</properties>
<dependencies>
<dependency>
<groupId>io.github.linpeilie</groupId>
<artifactId>mapstruct-plus-spring-boot-starter</artifactId>
<version>${mapstruct-plus.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>1.8</source>
<target>1.8</target>
<annotationProcessorPaths>
<path>
<groupId>io.github.linpeilie</groupId>
<artifactId>mapstruct-plus-processor</artifactId>
<version>${mapstruct-plus.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
指定对象映射关系:
在 User
或者 UserDto
上面增加注解 —— @AutoMapper
,并设置 targetType
为对方类。
例如:
@AutoMapper(target = UserDto.class)
public class User {
// ...
}
测试:
@SpringBootTest
public class QuickStartTest {
@Autowired
private Converter converter;
@Test
public void test() {
User user = new User();
user.setUsername("jack");
user.setAge(23);
user.setYoung(false);
UserDto userDto = converter.convert(user, UserDto.class);
System.out.println(userDto); // UserDto{username='jack', age=23, young=false}
assert user.getUsername().equals(userDto.getUsername());
assert user.getAge() == userDto.getAge();
assert user.isYoung() == userDto.isYoung();
User newUser = converter.convert(userDto, User.class);
System.out.println(newUser); // User{username='jack', age=23, young=false}
assert user.getUsername().equals(newUser.getUsername());
assert user.getAge() == newUser.getAge();
assert user.isYoung() == newUser.isYoung();
}
}
小结:
引入依赖后,使用 MapStructPlus 的步骤非常简单。
AutoMapper
注解;Converter
实例,调用 convert
方法即可。该项目开发一段时间了,也逐渐趋于稳定,已在多个项目中正式应用,如果有帮助的话,求 star ~
1
zhouhu 291 天前
其实 我感觉手写更方便,调试也简单。简单项目的话 db model 直接用
|
2
taogen 291 天前 2
给我的感觉:就这?
Spring 不是有现成了方法吗。BeanUtils.copyProperties(Object source, Object target) 至少展示一些亮点出来。 |
4
huiyadanli 291 天前 3
@taogen 两者性能不是一个级别的。这个项目是 MapStruct 的易用包装。
而且 BeanUtils.copyProperties 甚至在有些公司已经被禁止使用了。 建议先了解下再回复,不然一个“就这?”会让人觉的你无知又狂妄。 |
5
taogen 291 天前 3
|
6
huiyadanli 291 天前
@taogen #5 抱歉,忽略了 Spring 开头。不过 MapStruct 是另外一种思路,可以了解下。虽然个人更加喜欢用 idea 插件直接一把生成对象互转的方法。
|
7
kuituosi 291 天前
不错,已 star
|
8
mmdsun 291 天前
借楼 想问问,MapStruct 支持深拷贝吗?嵌套大对象的性能怎么样?
很多框架,对象里面嵌套的对象拷贝只支持引用,一修改就都修改了。 |
10
RedBeanIce 291 天前
楼主加油,冲啊!
上面的部分人估计没写过复杂项目。 |
11
eleganceoo 291 天前
楼主加油,很多 bean 八九十个字段,的确需要这样的方法,目前使用 hutool BeanUtil
|
12
chuck1in 291 天前
@huiyadanli 国内的技术人员里面很多这种喜欢莫名其妙贬低别人的人。不知道为啥内心这么阴暗。
另外想已经 star op 的仓库了,求互相 star 。 https://github.com/ccmjga/mjga-scaffold https://www.mjga.cc |
13
litchinn 291 天前 2
本来是推自己的 mapstructplus 的,变成讨论 mapstruct 的了,哈哈
mapstruct 本身是通过编译期生成 getset 方法来实现转换的,就和 lombok 生成 getset 方法一样,因此这两者同时使用还需要额外配置 因为是 getset ,所以 mapstruct 的性能要优于 BeanUtils.copyProperties ,通常认为偶尔使用且数据量小的情况可以直接使用 BeanUtils.copyProperties ,否则使用 mapstruct 或者自己写 getset 比较好 关于深度拷贝,mapstruct 是支持的,也是需要额外的配置,不复杂 mapstruct 还提供 SPI 回到楼主这,楼主说 plus 对 mapstruct 做了增强,也就是连本来需要自己写的 Mapper 也通过 mapstruct-plus-processor 生成了。感觉楼主介绍的时候得强调下你做了哪些增强,本来是啥样,之后是啥样,例如楼上问到的深拷贝等,在你这里应该如何使用。 最后想问下,这个 @AutoMapper 支持多个 target 吗,如果我 User 想转成多种 UserVO 要怎么使用呢? |
18
alva0 OP @RedBeanIce 🤣感谢支持
|
19
alva0 OP @eleganceoo 可以体验下
|
20
alva0 OP @litchinn 本来也是基于 mapstruct 实现的。
主要是省略手写 Mapper 的过程,通过在类上面增加注解的方式,来生成转换接口,这是最主要的增强。同时还有一些别的,可以看下文档。 支持多个,可以通过注解 @AutoMappers 来配置多个类 |
22
rockyastor 291 天前
公司内是大量但不深度使用 mapstruct 的,这样一个 plus 库很实用,已 star !
|
23
alva0 OP @rockyastor 也是为了解决自己的痛点,开源出来的,感觉支持😁
|
24
zhazi 291 天前 2
这个么一个小 kit 和整个 spring 生态做耦合,里面还塞了一个 hutool 的大杂烩,也没有测试
|
26
Aresxue 291 天前
有对应的 idea 插件吗,当字段类型不一致时做提示(可配置为严格模式,严格模式直接报编译错误),还有两个实体的字段差异最好也能在悬浮窗上展现出来,感觉现有的 bean copy 在这方面都不咋的。
|