1.pom引入依赖
<properties>
<java.version>1.8</java.version>
<mapstruct.version>1.3.0.Final</mapstruct.version>
</properties>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>${mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</dependency>
引入lombok 注解替代get set方法
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
</dependency>
2.创建DO DTO 以person user 为例,user为person的一个属性 PersonDto为传输层
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Person {
private Long id;
private String name;
private String email;
private Date birthday;
private User user;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer age;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class PersonDTO {
private Long id;
private String name;
/**
* 对应 Person.user.age
*/
private Integer age;
private String email;
/**
* 与 DO 里面的字段名称(birthDay)不一致
*/
private Date birth;
/**
* 对 DO 里面的字段(birthDay)进行拓展,dateFormat 的形式
*/
private String birthDateFormat;
/**
* 对 DO 里面的字段(birthDay)进行拓展,expression 的形式
*/
private String birthExpressionFormat;
}
3.编写接口,componentModel = “Spring” 交给spring管理
/* 1.源对象属性 与 目标对象属性 名字一致,自动映射对应属性
* 2.支持表达式的方式,例如可以用 format 转成自己想要的类型
* 3.如果某个属性你不想映射,可以加个 ignore=true
* 4.可以看到像 id、name、email这些名词一致的我并没有指定 source-target
* 而birthday-birth指定了,转换格式的 birthDateFormat 加了dateFormat
* 或者 birthExpressionFormat 加了 expression
*/
@Mapper(componentModel = "Spring")
public interface PersonConverter {
PersonConverter INSTANCE = Mappers.getMapper(PersonConverter.class);
@Mapping(source = "birthday",target = "birth")
@Mapping(source = "birthday",target = "birthDateFormat",dateFormat = "yyyy-HH-dd HH:mm:ss")
@Mapping(target = "birthExpressionFormat",dateFormat = "yyyy-HH-dd HH:mm:ss")
@Mapping(source = "email",target = "email",ignore = true)
PersonDTO toConvertPerson(Person person);
List<PersonDTO> toConvertList(List<Person> person);
}
4.测试
4.1pom引入单元测试
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
4.2编写测试类
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = MapStructDemoApplication.class)
public class PersonConvertTest {
@Autowired
private PersonConverter personConverter;
@Test
public void test(){
Person person = new Person(1L,"音乐土豆","*****@qq.com",new Date(),new User(1));
PersonDTO personDTO = personConverter.toConvertPerson(person);
System.out.println(personDTO);
List<Person> list = new ArrayList<>();
list.add(person);
List<PersonDTO> personDTOS = personConverter.toConvertList(list);
personDTOS.forEach(personDto-> System.out.println(personDto));
}
}
输出:
遇到的问题:
idea启动报错,java: Internal error in the mapping processor: java.lang.NullPointerException at org.ma…
解决方法:
1.设置File→settings→Compiler的User-local build process VM options (overrides Shared options)选项设置
-Djps.track.ap.dependencies=false
注解说明:
@Mapper 只有在接口加上这个注解, MapStruct 才会去实现该接口
@Mapper 里有个 componentModel 属性,主要是指定实现类的类型,一般用到两个
default:默认,可以通过 Mappers.getMapper(Class) 方式获取实例对象
spring:在接口的实现类上自动添加注解 @Component,可通过 @Autowired 方式注入
@Mapping:属性映射,若源对象属性与目标对象名字一致,会自动映射对应属性
source:源属性
target:目标属性
dateFormat:String 到 Date 日期之间相互转换,通过 SimpleDateFormat,该值为 SimpleDateFormat 的日期格式
ignore: 忽略这个字段
@Mappings:配置多个@Mapping
@MappingTarget 用于更新已有对象
@InheritConfiguration 用于继承配置
idea安装插件