MapStruct转换器
/documentation/stable/reference/html/#defining-mapper 更多详情见官方文档
<dependency>
<groupId></groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>1.3.</version>
</dependency>
<dependency>
<groupId></groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.3.</version>
</dependency>
常见问题
1.注:如果项目中使用了lombok,那么需要在编译器指定他们的执行顺序,因为mapstrut底层是靠set/get赋值的,所以需要lombok先编译。
<plugin>
<groupId></groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
<annotationProcessorPaths>
<path>
<groupId></groupId>
<artifactId>lombok</artifactId>
<version>${}</version>
</path>
<path>
<groupId></groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
2.注: 出现问题 Couldn’t retrieve @Mapper annotation
-
可能是 项目中使用了swagger,swagger里面也包含mapstruct,排除掉就好
<dependency> <groupid></groupid> <artifactid>springfox-swagger2</artifactid> <version>${}</version> <scope>compile</scope> <exclusions> <exclusion> <groupid></groupid> <artifactid>mapstruct</artifactid> </exclusion> </exclusions> </dependency>
-
同时使用了 mapstruct-jdk8 和 mapstruct-processor 但版本不一致,将版本号改为一样即可
3.注:出现问题
java: Internal error in the mapping processor: at (:182)
在使用MapStruct,idea2020.3版本在build项目的时候出现错误:java: Internal error in the mapping processor:
解决:
Setting -->Build,Execution,Deployment -->Compiler -->User-local build
加上参数:
-=false
版本要求
mapstruts的版本不是随意的,需要和mybatis-plus和springboot兼容,可在/页面查询依赖版本。
现以尝试出无问题对应版本:
<!--mybatis-plus-->
<dependency>
<groupId></groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.1</version>
</dependency>
<!-- mybatis-plus-generator -->
<dependency>
<groupId></groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId></groupId>
<artifactId>beetl</artifactId>
<version>3.1.</version>
</dependency>
<!-- MapStruct-->
<dependency>
<groupId></groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>1.2.</version>
</dependency>
<dependency>
<groupId></groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.2.</version>
</dependency>
springboot :2.3.
<!-- mybatis-plus -->
<dependency>
<groupId></groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3.1</version>
</dependency>
<!-- mybatis-plus-generator -->
<dependency>
<groupId></groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.4.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId></groupId>
<artifactId>beetl</artifactId>
<version>3.1.</version>
</dependency>
<!-- MapStruct-->
<dependency>
<groupId></groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>1.3.</version>
</dependency>
<dependency>
<groupId></groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.3.</version>
</dependency>
springboot :2.3.
@Mapping
/weixin_44131922/article/details/126232977
Mappings 可以理解为一个 普通 Mapping 的父标签,允许里面放多个 Mapping 使用 ,分割与直接写 多个Mapping 没什么区别
1.手动定义转换字段名不匹配的熟悉
@Mappings({
@Mapping(source = "id", target = "userId"),
@Mapping(source = "username", target = "name"),
@Mapping(source = "", target = "roleName")
})
2.当原属性没有指定默认值时
@Mapping(source = "", target = "choice", defaultValue = "给个默认值")
3.一般的类型以及日期转换(dateFormat), 数字转换(numberFormat)
@Mapping(source = "", target = "strTime", dateFormat = "yyyy-MM-dd")
@Mapping(source = "", target = "ap", numberFormat = "#0.00岁")
官方支持的基本类型自动转换大致如下:
1.基本类型及其对应的包装类之间:比如, int 和 Integer, float 和 Float, long 和 Long,boolean 和 Boolean 等
2.任意基本类型与任意包装类之间:如 int 和 long, byte 和 Integer 等
3.所有基本类型及包装类与String之间:如 boolean 和 String, Integer 和 String, float 和 String 等
4.枚举和String之间。
大数类型(, ) 和Java基本类型(包括其包装类)与String之间
表达式以及 Mappings
Expression 可以用来替代 source 中的一般属性,允许直接写入一般的 java 表达式,即自己提供source 的表达式,但目前支持 Java 一种语言。
@Mapping(expression = "java( new () )", target = "timeAA")
5.转换时 不使用对象中的同名属性 使用指定参数作为某一属性的值
PersonVO PersionDTO均含有PId 但是我并不想使用对象中的值而是采用我传入的值
@Mapping(source = "id", target = "PId")
public abstract PersonVO transToViewObject2(PersionDTO persionDTO, Long id);
6.类作为属性时
与一般的引用类型一致,当两个类中都含有某一个同类型的同名属性时,即使是类也会自动映射,如果类型一致,但是名称不一致,则指定名称后依旧会自动映射
7.@InheritInverseConfiguration 逆映射
/sinat_32787481/article/details/110928756 高级映射
@InheritConfiguration注解的方法上,有需要映射的字段,它会搜索有相同配置的映射,找到了直接复用此映射;若找到多个方法上都有满足此映射的配置,需要制定**@InheritConfiguration#name**的值,制定继承方法的映射。
一个文件内,两个类之间互相转换映射时其实只要写好其中一个映射,另一个可以通过注解继承原有映射配置,即原有的 target 与 source 会互换
@Mapping(source = "describe", target = "des")
@Mapping(source = "apee", target = "apee2")
public abstract PersonVO transToViewObject(PersionDTO persionDTO);
@InheritInverseConfiguration
public abstract PersionDTO transToViewObject(PersonVO personVO);
8.自定义映射 ,list, Map, 枚举
自定义映射
// 自定义的映射方法:转换boolen为String时,做一些判断然后返回对应的值。
@Named("DoneFormater")
public class DoneFormater {
@Named("DoneFormater")
public String toStr(Boolean isDone) {
if (isDone) {
return "已完成";
} else {
return "未完成";
}
}
@Named("DoneDetailFormater")
public String toDetail(Boolean isDone) {
if (isDone) {
return "该产品已完成";
} else {
return "该产品未完成";
}
}
public Boolean toBoolean(String str) {
if (str.equals("已完成")) {
return true;
} else {
return false;
}
}
}
// 通过uses 来导入上面我们写的 自定义映射方法
@Mapper( uses = {DoneFormater.class})
public interface ObjectQualiferMapper {
ObjectQualiferMapper INSTANCE = Mappers.getMapper(ObjectQualiferMapper.class);
// 当有多个方法 拥有一样的参数和返回类型时,需要指定使用其中的哪一个,使用qualifiedByName指定
@Mapping(source = "isDone", target = "isDone", qualifiedByName = "DoneDetailFormater")
ProductDTO toDto(Product product);
}
List映射
@Mapper(componentModel = "spring")
public interface UserMapping {
/**
* Student 转化为 User
* @param Student
* @return
*/
User studentToUser(Student student);
// 当执行 下面这个List的转换时,会遍历list: students,
// 然后自动调用上面的Student转User的转换方法,来进行转换
/**
* Students 转化为 Users
* @param Students
* @return
*/
List<user> studentsToUsers(List<student> students);
}
map映射
@MapMapping(valueDateFormat = "yyyy-MM-dd HH:mm:ss")
Map<string, string=""> toDTO(Map<long, date=""> map);
枚举
public enum E1 {
E1_1,
E1_2,
E1_3
}
public enum E2 {
E2_1,
E2_2,
E2_3
}
映射方法:使用@ValueMappings和@ValueMapping ,可以理解成是用if判断枚举值,然后返回对应结果
@ValueMappings({
@ValueMapping(target = "E1_1", source = "E2_1"),
@ValueMapping(target = "E1_2", source = "E2_2"),
@ValueMapping(target = MappingConstants.NULL, source = "E2_3") //转换成null
})
E1 toDTO(E2 e2);