1.什么是Mapper?
MapStruct是一个代码生成器,它基于convention over configuration(约定优于配置)的思想,极大地简化了 Java bean 类型之间转换。
1.2 为什么使用mapstruct?
JAVA开发按照传统的MVC或DDD模型开发时,各层传输之间的bean类型不同会涉及到大量的bean转换,比如: DO、BO、DTO、entity、VO等
1.2 使用mapstruct优点 与缺点分别是什么?
*优点:
mapstruct是在编译时完成Bean转换,与内存式(BeanUtils.copy…)对比,提升了服务性能。
mapstruct是在编译时完成Bean转换, 编译后在target目录,生成对应的xxximp.java文件,代码对开发人员透明,方便定位bug。
2.项目中如何引入mapstruct
<!-- 引入pom依赖 -->
...
<properties>
<lombok.version>1.18.16</lombok.version>
<org.mapstruct.version>1.4.2.Final</org.mapstruct.version>
</properties>
...
<dependencies>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${org.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>1.8</source>
<target>1.8</target>
<annotationProcessorPaths>
<!-- other annotation processors -->
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
...
3 mapstruct如何使用(语法说明): 直接贴代码
3.1 方式1
@Mapper
public interface CarMapper {
//静态成员
CarMapper INSTANCE = Mappers.getMapper( CarMapper.class );
// 转换函数的定义
@Mapping(source = "numberOfSeats", target = "seatCount")
CarDto carToCarDto(Car car); 2
}
3.1 方式2
//将bean交给spring管理, --> componentModel = "spring"
//目标属性未匹配时系统忽略,不打印警告日志 -->unmappedTargetPolicy = ReportingPolicy.IGNORE
// 公共的转换组件引用 --> uses = {ConvertUtil.class}
@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE, uses = {ConvertUtil.class}, componentModel = "spring")
public interface CarMapper {
// 转换函数的定义
@Mapping(source = "numberOfSeats", target = "seatCount")
CarDto carToCarDto(Car car); 2
}
3.2 @Mapper语法小样
// 示例小样1
@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE, uses = ConvertUtil.class, componentModel = "spring")
// 指定默认值
@Mapping(target = "name", source="name", defaultValue = "我是默认值")
// 使用java可执行代码或函数
@Mapping(target = "name", expression = "java(\"OT\" + paramBean.getId())")
// 使用常量代替默认值
@Mapping(target = "stringConstant", constant = "Constant Value")
//日期格式化
@Mapping(source = "birthday", target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss")
// Integer 到 String的转换
@Mapping(source = "price", numberFormat = "$#.00")
//Date 转字符串
@Mapping(source = "currentDate", dateFormat = "dd.MM.yyyy")
@Mappings({
@Mapping(source = "birthday", target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss"),
@Mapping(source = "name", target = "name")
})
@IterableMapping(dateFormat = "dd.MM.yyyy")
List<String> dateToString(List<Date> dates)
// 引用另一个映射器类
@Mapper(uses = PrivateDateMapper.class)
public class CartMapper {
CartDto cartToCartDto(Cart cart);
}
public class DateMapper {
public String asString(Date date) {
... ...
}
public Date toDate(String date) {
... ...
}
}
// 示例小样2 DO 转 DTO
public interface PersonDo2DtoMapping {
PersonDo2DtoMapping INSTANCE = Mappers.getMapper(PersonDo2DtoMapping.class);
@Mapping(source = "birthday", target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss")
PersonDto do2dto(PersonDo personDo);
}
// 示例小样3 DO集合 转 DTO集合:
public interface PersonDo2DtoMapping {
PersonDo2DtoMapping INSTANCE = Mappers.getMapper(PersonDo2DtoMapping.class);
@Mapping(source = "birthday", target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss")
PersonDto do2dto(PersonDo personDo);
// 会使用domain2dto方法进行对象list转换
// 集合的bean的转换本质是:转换的时候调用了do2dto方法,也就是说mapsstruct能自动的使用合适的转换方法
List<PersonDto> listToList(List<PersonDo> people);
}
//示例小样4 多个类型的 DO 转换为一个类型的 DTO
public interface PersonDo2DtoMapping {
PersonDo2DtoMapping INSTANCE = Mappers.getMapper(PersonDo2DtoMapping.class);
@Mapping(source = "psersonDo.birthday", target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss")
@Mapping(source = "userDo.name", target = "name")
PersonDto twoDoTOTwoDto(PersonDo personDo,UserDO userDo);
}
//示例小样5 自定义DO 转 DTO 的映射规则
// eg:比如的用户性别sex DO对应的是Integer类型{0:男,1:女}, DTO对应的是String类型{0:男,1:女}
/**定义PersonSexConverterRule 转换规则类*/
public class PersonSexConverterRule {
public String intToString(int sex) {
if (sex == 0) {
return "男";
} else {
return "女";
}
}
}
@Mapper(uses = PersonSexConverterRule.class)
public interface PersonDo2DtoMapping {
PersonDo2DtoMapping INSTANCE = Mappers.getMapper(PersonDo2DtoMapping.class);
// ?? 规则作用在哪个属性上,是根据属性类型进行规则匹配的?
@Mapping(source = "birthday", target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss")
PersonDto do2dto(PersonDo personDo);
}
//示例小样6 spring整合:需要在映射接口的mapper注解中添加参数componentModel = "spring"
@Mapper(uses = PersonSexConverterRule.class,componentModel = "spring")
public interface PersonDo2DtoMapping {
PersonDo2DtoMapping INSTANCE = Mappers.getMapper(PersonDo2DtoMapping.class);
// ?? 规则作用在哪个属性上,是根据属性类型进行规则匹配的?
@Mapping(source = "birthday", target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss")
PersonDto do2dto(PersonDo personDo);
}
版权声明:本文为zhlin110228323原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。