概述
MapStruct是一个Java注释处理器,用于生成类型安全的bean映射类。
您要做的就是定义一个映射器接口,该接口声明任何必需的映射方法。在编译期间,MapStruct将生成此接口的实现。此实现使用简单的Java方法调用在源对象和目标对象之间进行映射,即没有反射或类似内容。
与手动编写映射代码相比,MapStruct通过生成繁琐且易于出错的代码来节省时间。遵循配置方法上的约定,MapStruct使用合理的默认值,但在配置或实现特殊行为时不加理会。
与动态映射框架相比,MapStruct具有以下优点:
通过使用普通方法调用(settter/getter)而不是反射来快速执行
编译时类型安全性:只能映射相互映射的对象和属性,不能将order实体意外映射到customer DTO等。
如果有如下问题,编译时会抛出异常
3.1 映射不完整(并非所有目标属性都被映射)
3.2 映射不正确(找不到正确的映射方法或类型转换)
为什么要用 MapStruct
MapStruct出现之前项目中大多用的都是BeanUtils.copy...此类的方式。BeanUtils缺陷明显比如 效率低下、复杂属性的复制问题、内嵌对象的复制问题。这些问题都可以在MapStruct中得到很好的解决。
MapStruct依赖
<!--mapstruct插件依赖-->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.5.0.Final</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.0.Final</version>
</dependency>
测试实体类
import lombok.Data;
import java.util.List;
@Data
public class Student {
private String name;
private int age;
private List<String> course;
}
import lombok.Data;
import java.util.List;
@Data
public class StudentVo {
private String name;
private int age;
// 此处课程名称不一样
private List<String> courses;
}
映射接口类(加强了复杂属性的替换)
@Mapper 接口类注解
@Mapping 接口类方法注解(复杂属性的替换)
其他属性可以查看源码---很简单
import com.dahan.bean.Student;
import com.dahan.vo.StudentVo;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
/**
* 转换类映射类
*/
@Mapper
public interface StudentMapper {
StudentMapper INSTANCE = Mappers.getMapper(StudentMapper.class);
@Mapping(source = "course", target = "courses")
StudentVo convert(Student student);
}
测试类
package com.dahan;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.fastjson.JSON;
import com.dahan.bean.Student;
import com.dahan.model.StudentMapper;
import com.dahan.vo.StudentVo;
public class MapStructTest {
public static void main(String[] args) {
Student studentSource = new Student();
studentSource.setName("刘德华");
studentSource.setAge(60);
List<String> strings = new ArrayList<>();
strings.add("语文");
strings.add("数学");
strings.add("物理");
studentSource.setCourse(strings);
StudentVo studentTarget = StudentMapper.INSTANCE.convert(studentSource);
System.out.println("Student: " + JSON.toJSONString(studentSource));
System.out.println("StudentVo: " + JSON.toJSONString(studentTarget));
}
}