开源项目 mapstruct 代替 BeanUtils
共 6477字,需浏览 13分钟
·
2021-10-22 09:27
不点蓝字关注,我们哪来故事?
![](https://filescdn.proginn.com/dba427b8fa6812a1a678ab045311c880/08d6dc8bd489a5b1225c8c7cc38763e0.webp)
正文如下
来源:toutiao.com/i6891531055631696395/
老铁们是不是经常为写一些实体转换的原始代码感到头疼,尤其是实体字段特别多的时候。介绍一个开源项目 mapstruct ,可以轻松优雅的进行转换,简化你的代码。当然有的人喜欢写get set,或者用BeanUtils 进行复制,代码只是工具,本文只是提供一种思路。
先贴下官网地址吧:https://mapstruct.org/
废话不多说,上代码:
pom 配置:
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<maven.compiler.source>1.8maven.compiler.source>
<maven.compiler.target>1.8maven.compiler.target>
<org.mapstruct.version>1.4.1.Finalorg.mapstruct.version>
<org.projectlombok.version>1.18.12org.projectlombok.version>
properties>
<dependencies>
<dependency>
<groupId>org.mapstructgroupId>
<artifactId>mapstructartifactId>
<version>${org.mapstruct.version}version>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>${org.projectlombok.version}version>
<scope>providedscope>
dependency>
<dependency>
<groupId>org.mapstructgroupId>
<artifactId>mapstruct-processorartifactId>
<version>${org.mapstruct.version}version>
<scope>providedscope>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<version>3.8.1version>
<configuration>
<source>1.8source>
<target>1.8target>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>${org.projectlombok.version}version>
path>
<path>
<groupId>org.mapstructgroupId>
<artifactId>mapstruct-processorartifactId>
<version>${org.mapstruct.version}version>
path>
annotationProcessorPaths>
configuration>
plugin>
plugins>
build>
关于lombok和mapstruct的版本兼容问题多说几句,maven插件要使用3.6.0版本以上、lombok使用1.16.16版本以上,另外编译的lombok mapstruct的插件不要忘了加上。否则会出现下面的错误:No property named "aaa" exists in source parameter(s). Did you mean "null"?
这种异常就是lombok编译异常导致缺少get setter方法造成的。还有就是缺少构造函数也会抛异常。
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private String name;
private int age;
private GenderEnum gender;
private Double height;
private Date birthday;
}
public enum GenderEnum {
Male("1", "男"),
Female("0", "女");
private String code;
private String name;
public String getCode() {
return this.code;
}
public String getName() {
return this.name;
}
GenderEnum(String code, String name) {
this.code = code;
this.name = name;
}
}
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class StudentVO {
private String name;
private int age;
private String gender;
private Double height;
private String birthday;
}
@Mapper
public interface StudentMapper {
StudentMapper INSTANCE = Mappers.getMapper(StudentMapper.class);
@Mapping(source = "gender.name", target = "gender")
@Mapping(source = "birthday", target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss")
StudentVO student2StudentVO(Student student);
}
实体类是开发过程少不了的,就算是用工具生成肯定也是要有的,需要手写的部分就是这个Mapper的接口,编译完成后会自动生成相应的实现类
![](https://filescdn.proginn.com/5ccd3796f12373fbb72ed8f25143e7ef/74f0ba3d3f4923027076f92e10785b36.webp)
然后就可以直接用mapper进行实体的转换了
public class Test {
public static void main(String[] args) {
Student student = Student.builder().name("小明").age(6).gender(GenderEnum.Male).height(121.1).birthday(new Date()).build();
System.out.println(student);
//这行代码便是实际要用的代码
StudentVO studentVO = StudentMapper.INSTANCE.student2StudentVO(student);
System.out.println(studentVO);
}
}
![](https://filescdn.proginn.com/5ccd3796f12373fbb72ed8f25143e7ef/74f0ba3d3f4923027076f92e10785b36.webp)
mapper可以进行字段映射,改变字段类型,指定格式化的方式,包括一些日期的默认处理。
可以手动指定格式化的方法:
@Mapper
public interface StudentMapper {
StudentMapper INSTANCE = Mappers.getMapper(StudentMapper.class);
@Mapping(source = "gender", target = "gender")
@Mapping(source = "birthday", target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss")
StudentVO student2StudentVO(Student student);
default String getGenderName(GenderEnum gender) {
return gender.getName();
}
}
上面只是最简单的实体映射处理,下面介绍一些高级用法
1、List 转换
属性映射基于上面的mapping配置
@Mapper
public interface StudentMapper {
StudentMapper INSTANCE = Mappers.getMapper(StudentMapper.class);
@Mapping(source = "gender.name", target = "gender")
@Mapping(source = "birthday", target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss")
StudentVO student2StudentVO(Student student);
List students2StudentVOs(List studentList) ;
}
public static void main(String[] args) {
Student student = Student.builder().name("小明").age(6).gender(GenderEnum.Male).height(121.1).birthday(new Date()).build();
List list = new ArrayList<>();
list.add(student);
List result = StudentMapper.INSTANCE.students2StudentVOs(list);
System.out.println(result);
}
![](https://filescdn.proginn.com/aead8bdf1a4c1595f4c24764b6955c45/e27742558368981c4cf4b6bc85f559fc.webp)
2、多对象转换到一个对象
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private String name;
private int age;
private GenderEnum gender;
private Double height;
private Date birthday;
}
@Data
@AllArgsConstructor
@Builder
@NoArgsConstructor
public class Course {
private String courseName;
private int sortNo;
private long id;
}
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class StudentVO {
private String name;
private int age;
private String gender;
private Double height;
private String birthday;
private String course;
}
@Mapper
public interface StudentMapper {
StudentMapper INSTANCE = Mappers.getMapper(StudentMapper.class);
@Mapping(source = "student.gender.name", target = "gender")
@Mapping(source = "student.birthday", target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss")
@Mapping(source = "course.courseName", target = "course")
StudentVO studentAndCourse2StudentVO(Student student, Course course);
}
public class Test {
public static void main(String[] args) {
Student student = Student.builder().name("小明").age(6).gender(GenderEnum.Male).height(121.1).birthday(new Date()).build();
Course course = Course.builder().id(1L).courseName("语文").build();
StudentVO studentVO = StudentMapper.INSTANCE.studentAndCourse2StudentVO(student, course);
System.out.println(studentVO);
}
}
![](https://filescdn.proginn.com/5625669b76a4b4b1b9ec9b913d22c3bf/d3ba457464237c464465a28ea25ede5e.webp)
3、默认值
@Mapper
public interface StudentMapper {
StudentMapper INSTANCE = Mappers.getMapper(StudentMapper.class);
@Mapping(source = "student.gender.name", target = "gender")
@Mapping(source = "student.birthday", target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss")
@Mapping(source = "course.courseName", target = "course")
@Mapping(target = "name", source = "student.name", defaultValue = "张三")
StudentVO studentAndCourse2StudentVO(Student student, Course course);
}
![](https://filescdn.proginn.com/6b28379bf105d3aa6ccf68afade3759d/dd70bd9dc3adcec28bafb0d313b34b8f.webp)
往期推荐
-END-
↑ 点击上方关注我公号 ↑
半吊子的自己在试错,不知道以后会干什么,但享受现在的试错,试错给我惊讶的生活
喜欢公号的互动分享,感谢关注,路上遇见了你,同一小段时间之路,相伴 ~
长按识别,加我微信
![](https://filescdn.proginn.com/5f1ec18c5b54e4bc0bca1a9c37409908/6af96f67f952cc0a7700ca2e0ceb6787.webp)
点个在看结对编程一把
![](https://filescdn.proginn.com/aeabbffa07ec0cdba7d10a1f25b7335c/088bb13e2f8d25a5faf60f5fdd979c0b.webp)