# mapstruct-demo
**Repository Path**: note-java/mapstruct-demo
## Basic Information
- **Project Name**: mapstruct-demo
- **Description**: mapstruct笔记
- **Primary Language**: Java
- **License**: MIT
- **Default Branch**: dev
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 0
- **Created**: 2023-12-29
- **Last Updated**: 2025-06-11
## Categories & Tags
**Categories**: Uncategorized
**Tags**: MapStruct
## README
# MapStruct
## 介绍
#### MapStruct 学习笔记
MapStruct 是一款强大的 Java 工具,专注于解决不同对象间的高效复制问题,如 PO(持久对象)、DTO(数据传输对象)、VO(视图对象)以及 QueryParam 之间的转换。相较于基于反射机制的 BeanUtils 类库,MapStruct 利用编译器生成针对性的方法,显著提升了转换性能。
#### JavaBean 转换问题背景
在实际开发中,我们常常面临众多 JavaBean 间的相互转换需求。过去,常见的处理方式包括:
- ##### **拷贝技术**
- 使用 Apache Commons 的 PropertyUtils.copyProperties 或 BeanUtils.copyProperties
- Spring Framework 的 BeanUtils.copyProperties
- CGLIB 的 BeanCopier 类进行快速拷贝
- ##### **手动 get/set**
- 部分开发者借助 IDE 插件自动填充 set 方法实现对象复制,但这种方法可能并不为所有开发者熟知
- 即使如此,当新增字段时仍需手动更新,并且存在代码冗余和开发效率较低的问题
#### MapStruct 解决方案
MapStruct 是一款基于 Java 注解处理器的框架,它能够自动生成类型安全的 Bean 映射类。开发者只需定义一个映射器接口并声明所需的方法,编译阶段,MapStruct 就会创建对应的接口实现。这个实现利用简单的 Java get、set 方法执行源对象到目标对象的映射操作,而非依赖反射。
#### MapStruct 优势概述
1. **提高开发效率**:通过自动生成复杂的映射代码,避免了手写过程中可能出现的错误和繁琐劳动。
2. **编译时类型安全**:确保只有能互相匹配的对象及属性才能完成映射,有效防止诸如将订单实体误映射至客户 DTO 等错误发生。
3. **即时编译反馈**:当映射不完全(即未映射所有目标属性)或映射不正确(例如找不到适当的映射方法或类型转换时),编译器会在编译阶段就发出警告提示。
## 使用
#### 引入maven依赖
```
...
1.5.5.Final
1.18.20
0.2.0
...
org.mapstruct
mapstruct
${org.mapstruct.version}
...
org.apache.maven.plugins
maven-compiler-plugin
3.8.1
1.8
1.8
org.mapstruct
mapstruct-processor
${org.mapstruct.version}
org.projectlombok
lombok
${lombok.version}
org.projectlombok
lombok-mapstruct-binding
${lombok-mapstruct-binding.version}
...
```
#### @Mapper配置项
| 选择 | 目的 | 违约 |
| :----------------------------------------------- | :----------------------------------------------------------- | :-------- |
| `mapstruct. suppressGeneratorTimestamp` | 如果设置为 ,则禁止在生成的映射器类的注释中创建时间戳。`true``@Generated` | `false` |
| `mapstruct.verbose` | 如果设置为 ,则 MapStruct 在其中记录其主要决策。请注意,在 Maven 中编写时,由于 maven-compiler-plugin 配置中存在问题,也需要添加。`true``showWarnings` | `false` |
| `mapstruct. suppressGeneratorVersionInfoComment` | 如果设置为 ,则禁止在生成的映射器类的注释中创建属性。注释包含有关 MapStruct 版本和用于注释处理的编译器的信息。`true``comment``@Generated` | `false` |
| `mapstruct.defaultComponentModel` | 应基于哪个映射器生成映射器的组件模型的名称(请参阅[检索映射器](https://mapstruct.org/documentation/stable/reference/html/#retrieving-mapper))。支持的值为:`default`:映射器不使用组件模型,实例通常通过`Mappers#getMapper(Class)``cdi`:生成的映射器是应用程序范围的(来自 javax.enterprise.context 或 jakarta.enterprise.context,取决于哪个映射器在 javax.inject 具有优先级的情况下可用)CDI bean,可以通过`@Inject``spring`:生成的映射器是单例范围的 Spring bean,可以通过`@Autowired``jsr330`:生成的映射器用 {@code @Named} 注释,可以通过(从 javax.inject 或 jakarta.inject,取决于 javax.inject 具有优先级的可用映射器)进行检索,例如使用 Spring`@Inject``jakarta`:生成的映射器用 {@code @Named} 注解,可以通过(来自 jakarta.inject)检索,例如使用 Spring`@Inject``jakarta-cdi`:生成的映射器是应用程序范围的(来自 jakarta.enterprise.context)CDI bean,可以通过`@Inject`如果通过 为特定映射器提供组件模型,则注释中的值优先。`@Mapper#componentModel()` | `default` |
| `mapstruct.defaultInjectionStrategy` | 映射器中通过参数 的注入类型。这仅用于基于注释的组件模型 例如 CDI、Spring 和 JSR 330。`uses`支持的值为:`field`:依赖项将被注入到字段中`constructor`:将生成构造函数。依赖项将通过构造函数注入。当 CDI 时,还将生成默认构造函数。 如果为特定映射器提供了注入策略 via ,则注解中的值优先于选项。`componentModel``@Mapper#injectionStrategy()` | `field` |
| `mapstruct.unmappedTargetPolicy` | 在映射方法的目标对象的属性未填充源值时要应用的默认报告策略。支持的值为:`ERROR`:任何未映射的目标属性都会导致映射代码生成失败`WARN`:任何未映射的目标属性都会在生成时引起警告`IGNORE`:忽略未映射的目标属性如果通过 为特定映射器提供策略,则注释中的值优先。 如果通过 为特定的 Bean 映射提供策略,则它优先于 both 和 选项。`@Mapper#unmappedTargetPolicy()``@BeanMapping#unmappedTargetPolicy()``@Mapper#unmappedTargetPolicy()` | `WARN` |
| `mapstruct.unmappedSourcePolicy` | 在映射方法的源对象的属性未填充目标值时应用的默认报告策略。支持的值为:`ERROR`:任何未映射的源属性都会导致映射代码生成失败`WARN`:任何未映射的源属性都会在生成时引起警告`IGNORE`:忽略未映射的源属性如果通过 为特定映射器提供策略,则注释中的值优先。 如果通过 为特定的 Bean 映射提供策略,则它优先于 both 和 选项。`@Mapper#unmappedSourcePolicy()``@BeanMapping#ignoreUnmappedSourceProperties()``@Mapper#unmappedSourcePolicy()` | `WARN` |
| `mapstruct. disableBuilders` | 如果设置为 ,则 MapStruct 在执行映射时将不会使用构建器模式。这相当于为所有映射器执行此操作。`true``@Mapper( builder = @Builder( disableBuilder = true ) )` | `false` |
#### @Mapping属性
```
target:目标属性的名称,必须指定。
source:源属性的名称,如果与目标属性名称相同,则可以省略。
dateFormat:指定日期类型属性的格式化方式,例如:"yyyy-MM-dd"。
numberFormat:指定数字类型属性的格式化方式,例如:"#.00"。
constant:指定目标属性的常量值。
expression:使用表达式来计算目标属性的值。
defaultExpression:在源属性为 null 的情况下,使用表达式来计算目标属性的默认值。
ignore:是否忽略该映射。
qualifiedBy:指定一个或多个限定符以选择适当的映射方法。
qualifiedByName:指定一个或多个限定符名称以选择适当的映射方法。
conditionQualifiedBy:指定一个或多个条件限定符以选择适当的映射方法。
conditionQualifiedByName:指定一个或多个条件限定符名称以选择适当的映射方法。
conditionExpression:使用表达式来计算是否应该执行映射。
resultType:指定映射结果类型。
dependsOn:指定当前映射依赖的其他映射方法。
defaultValue:在源属性为 null 且无默认表达式的情况下,指定目标属性的默认值。
nullValueCheckStrategy:控制是否检查源对象和目标对象上的 null 值。
nullValuePropertyMappingStrategy:在源对象或目标对象上存在 null 值属性的情况下,控制如何处理目标对象上的 null 值属性。
mappingControl:指定映射控制实现类。
```
注意事项:
- source与constant不能同时使用
- ***@BeanMapping(ignoreByDefault = true)***设置默认忽略未配置的属性
- numberFormat,使用DecimalFormat进行格式化,0:有就写没有就写0,#:有就写没有就不写,遵顼四舍五入原则
- expression需要写明具体包路劲,例***expression = "java(java.util.UUID.randomUUID().toString())"***
- qualifiedBy,与qualifiedByName类似可以绑定一个映射类,需要与@QName联用
- qualifiedByName需要与@QName联用
- conditionQualifiedBy与qualifiedBy类似,只适用于Condition方法
- conditionQualifiedByName同上
- ***@BeanMapping(resultType= Class>)***
## 定义映射器
#### 1.基本映射
```JAVA
import com.fjg.mapstructdemo.dto.UserInfoNew;
import com.fjg.mapstructdemo.dto.UserInfoOld;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
import java.util.List;
/**
* 基础映射
* @author fengjianguo
* @date 2023/12/29 13:42
*/
@Mapper
public interface UserInfoConvert {
UserInfoConvert INSTANCE = Mappers.getMapper(UserInfoConvert.class);
/**
* 旧的实体类转换为新的实体类
* @param userInfoOld
* @return
*/
@Mapping(source = "name",target = "userName")
@Mapping(source = "sex",target = "userSex")
@Mapping(source = "age",target = "userAge")
@Mapping(source = "address",target = "userAddress")
UserInfoNew convert(UserInfoOld userInfoOld);
/**
* 转换
*
* @param userInfoOlds 用户信息旧版
* @return {@link List}<{@link UserInfoNew}>
*/
List convert(List userInfoOlds);
}
```
##### 说明:
1. @Mapper注解会导致MapStruct代码生成器在构建时创建CarMapper接口的实现。
2. 在生成的方法实现中,源类型(例如UserInfoOld)的所有可读属性将被复制到目标类型(例如UserInfoNew)的相应属性中。
3. 当属性与目标实体的属性同名时,它们将被隐式映射。 当属性在目标实体中具有不同的名称时,可以通过@Mapping注解指定其名称。
4. 必须在@Mapping注解中指定属性名称,该名称定义在JavaBeans规范中,例如对于具有访问器方法getName()和setName()的属性,名称为name。可以结合Lombok使用。
#### 2.映射合成
```JAVA
import org.mapstruct.Mapping;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 元注解
* ElementType.TYPE:类、接口、枚举等类型。
* ElementType.FIELD:字段(成员变量)。
* ElementType.METHOD:方法。
* ElementType.PARAMETER:方法参数。
* ElementType.CONSTRUCTOR:构造函数。
* ElementType.LOCAL_VARIABLE:局部变量。
* ElementType.ANNOTATION_TYPE:注解类型。
* ElementType.PACKAGE:包。
* ElementType.TYPE_PARAMETER:泛型类型参数。
* ElementType.TYPE_USE:类型使用。
* RetentionPolicy.CLASS,表示该注解将在编译期间保留
* RetentionPolicy.SOURCE:表示该注解只会在源代码中存在,在编译后会被丢弃,不能被读取到。
* RetentionPolicy.RUNTIME:表示该注解将在运行期间保留,并能够通过反射机制访问到。
* @author fengjianguo
* @date 2023/12/29 14:08
*/
@Retention(RetentionPolicy.CLASS)
@Mapping(target = "id", expression = "java(java.util.UUID.randomUUID().toString())")
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
public @interface BaseEntity {
}
```
```JAVA
import com.fjg.mapstructdemo.dto.UserInfoNew;
import com.fjg.mapstructdemo.dto.UserInfoOld;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
import java.util.List;
/**
* 基础映射
* @author fengjianguo
* @date 2023/12/29 13:42
*/
@Mapper
public interface UserInfoConvert {
UserInfoConvert INSTANCE = Mappers.getMapper(UserInfoConvert.class);
/**
* 旧的实体类转换为新的实体类
* @param userInfoOld
* @return
*/
@BaseEntity
@Mapping(source = "name",target = "userName")
@Mapping(source = "sex",target = "userSex")
@Mapping(source = "age",target = "userAge")
@Mapping(source = "address",target = "userAddress")
UserInfoNew convert(UserInfoOld userInfoOld);
/**
* 转换
*
* @param userInfoOlds 用户信息旧版
* @return {@link List}<{@link UserInfoNew}>
*/
List convert(List userInfoOlds);
}
```
##### 说明:
1. MapStruct 支持使用元注解,可以将通用的映射部分抽取出来
#### 3.向映射器添加自定义方法
```JAVA
/**
* 旧的实体类转换为新的实体类
*
* @param userInfoOld
* @return
*/
@BaseEntity
@Mapping(source = "name", target = "userName")
@Mapping(source = "sex", target = "userSex")
@Mapping(source = "age", target = "userAge")
@Mapping(source = "address", target = "userAddress", qualifiedByName = "getAddress")
UserInfoNew convert(UserInfoOld userInfoOld);
/**
* 自定义默认方法
*
* @param address 地址
* @return {@link String }
*/
@Named("getAddress")
default String getAddress(String address) {
return address;
}
```
##### 说明:
1. 通过qualifiedByName与@Named进行绑定,在进行转换时找寻到该方法。
#### 4.多参数映射
```JAVA
/**
* 旧的实体类转换为新的实体类
*
* @param userInfoOld 用户信息旧
* @param userName 用户名
* @return {@link UserInfoNew }
*/
@Mapping(source = "userName", target = "userName")
@Mapping(source = "userInfoOld.sex", target = "userSex")
@Mapping(source = "userInfoOld.age", target = "userAge")
@Mapping(source = "userInfoOld.address", target = "userAddress")
UserInfoNew convert(UserInfoOld userInfoOld, String userName);
```
##### 说明:
1. 如果多个源对象都使用相同的属性名称进行定义,必须使用@Mapping注解来指定从哪个源参数获取属性,就像示例中的userName属性一样。如果不解决这种歧义,将引发错误。对于在给定的源对象中只存在一次的属性,可以选择性地指定源参数的名称,因为它可以自动确定。
2. 在使用@Mapping注解时,指定属性所在的参数是强制的。
3. 具有多个源参数的映射方法在所有源参数都为null的情况下将返回null。否则,将实例化目标对象,并将提供的参数的所有属性传播到目标对象。
#### 5.嵌套bean映射
```JAVA
@Mapping(source="userInfoOld", target = ".")
UserInfoOld toConvert(UserInfoNew userInfoNew);
```
##### 说明:
1. 生成的代码将直接UserInfoNew.userInfoOld的每个属性映射到UserInfoOld,无需手动命名它们。
2. @Mapping(source="userInfoOld", target = ".")的意思是将 UserInfoNew对象的userInfoOld属性的所有属性映射到UserInfoOld对象本身的属性中,而不是将其映射到 UserInfoOld对象的一个名为 userInfoOld的属性上。
#### 6.更新现有的bean
```JAVA
@Mapping(source = "userName", target = "userName")
@Mapping(source = "userInfoOld.sex", target = "userSex")
@Mapping(source = "userInfoOld.age", target = "userAge")
@Mapping(source = "userInfoOld.address", target = "userAddress")
void voidConvert(@MappingTarget UserInfoNew userInfoNew, UserInfoOld userInfoOld, String userName);
```
##### 说明:
1. 在某些情况下,可能需要进行映射操作,而不是创建目标类型的新实例,而是更新现有的实例。这种类型的映射可以通过添加一个目标对象参数,并使用@MappingTarget注解标记该参数来实现。
#### 7.反向映射
```JAVA
/**
* 旧的实体类转换为新的实体类
*
* @param userInfoOld
* @return
*/
@BaseEntity
@Mapping(source = "name", target = "userName")
@Mapping(source = "sex", target = "userSex")
@Mapping(source = "age", target = "userAge")
@Mapping(source = "address", target = "userAddress", qualifiedByName = "getAddress")
UserInfoNew convert(UserInfoOld userInfoOld);
/**
* 新的实体类转换为旧的实体类
*
* @param userInfoNew 用户信息新
* @return {@link UserInfoOld }
*/
@InheritInverseConfiguration
UserInfoOld convert(UserInfoNew userInfoNew);
```
##### 说明:
1. 为了减少重复编码,如果以及设置了正向映射(UserInfoOld => UserInfoNew)关系,可以直接通过@InheritInverseConfiguration进行反向映射(UserInfoNew => UserInfoOld )。
#### 8.map映射到bean
```JAVA
@BeanMapping(ignoreByDefault = true)
@Mapping(source = "name", target = "userName")
@Mapping(source = "sex", target = "userSex")
@Mapping(source = "age", target = "userAge")
@Mapping(source = "address", target = "userAddress")
UserInfoNew mapToBean(Map map);
```
##### 注意:
1. 如果目标对象存在嵌套的bean必须对嵌套的bean设置映射关系,或者将嵌套的bean进行忽略。
## 检索映射器(配置注入方式)
#### 1.工厂注入
```JAVA
@Mapper
public interface UserInfoConvert {
UserInfoConvert INSTANCE = Mappers.getMapper(UserInfoConvert.class);
UserInfoNew convert(UserInfoOld userInfoOld);
}
```
##### 说明:
1. 当不使用 DI 框架时,可以通过类检索 Mapper 实例。只需调用该方法,将映射器的接口类型传递给 return:`org.mapstruct.factory.Mappers``getMapper()`
#### 2.指定注入策略
```java
@Mapper(componentModel = MappingConstants.ComponentModel.SPRING
, uses = EngineMapper.class
, injectionStrategy = InjectionStrategy.CONSTRUCTOR)
public interface UserInfoConvert {
UserInfoConvert INSTANCE = Mappers.getMapper(UserInfoConvert.class);
/**
* 旧的实体类转换为新的实体类
*
* @param userInfoOld
* @return
*/
@BaseEntity
@Mapping(source = "name", target = "userName",qualifiedByName = "getEngineName")
@Mapping(source = "sex", target = "userSex")
@Mapping(source = "age", target = "userAge")
@Mapping(source = "address", target = "userAddress", qualifiedByName = "getAddress")
UserInfoNew convert(UserInfoOld userInfoOld);
}
@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
public interface EngineMapper {
/**
* 获取引擎名称
*
* @param engineName 发动机名称
* @return {@link String }
*/
@Named("getEngineName")
default String getEngineName(String engineName) {
return engineName + " engine";
}
}
```
##### 说明:
1. componentModel:指定了MapStruct生成的映射器实例应该被Spring管理。
2. uses:表示此映射器在进行映射时可能会用到`EngineMapper`类中的映射方法。有助于复用已定义的映射逻辑。
3. injectionStrategy:指定了MapStruct在注入依赖时应使用的策略为构造器注入。CONSTRUCTOR意味着MapStruct在生成映射器实现时,会优先通过构造器来注入依赖项,而不是使用字段注入或其他方式。
## 数据类型转换
#### 1.基本类型转换
mapstruct会自动完成基本类型的一些隐式转换(包括:boolean、byte、char、int、long、float、double、String及其包装类等)
相同基本类型可以直接转换
StringBuilder与String可以直接转换
大数类型与基本类型及其包装类、String可以直接转换
```JAVA
@Mapping(target = "intValue", source = "intValue")
@Mapping(target = "stringValue", source = "intValue")
@Mapping(target = "stringValue", source = "booleanValue")
// 强制转换,长字节类型转短字节类型会发生截断,注意数据溢出,精度丢失等问题。
@Mapping(target = "byteValue", source = "intValue")
// 基本类型与其包装类型可以直接转换,且会自动生成判空代码
@Mapping(target = "intValue", source = "integerValue")
```
#### 2.时间类型转换
隐式转换规则
1. java.time.Instant与java.util.Date直接转换
2. java.sql.Date与java.util.Date直接转换
3. java.sql.Time 与java.util.Date直接转换
4. java.sql.Timestamp 与java.util.Date直接转换
```JAVA
@Mapper
public interface TimeConvert {
TimeConvert INSTANCE = Mappers.getMapper(TimeConvert.class);
@Mapping(source = "localDateTime", target = "localDateTime", dateFormat = "yyyy-MM-dd HH:mm:ss")
@Mapping(source = "date", target = "date", dateFormat = "yyyy-MM-dd HH:mm:ss")
TimeNew convert(TimeOld timeOld);
}
@Data
public class TimeNew {
private String localDateTime;
private String date;
}
@Data
public class TimeOld {
private LocalDateTime localDateTime;
private Date date;
}
```
#### 3.集合类型转换
```JAVA
@BaseEntity
@Mapping(source = "name", target = "userName",qualifiedByName = "getEngineName")
@Mapping(source = "sex", target = "userSex")
@Mapping(source = "age", target = "userAge")
@Mapping(source = "address", target = "userAddress", qualifiedByName = "getAddress")
UserInfoNew convert(UserInfoOld userInfoOld);
/**
* 转换
*
* @param userInfoOlds 用户信息旧版
* @return {@link List}<{@link UserInfoNew}>
*/
List convert(List userInfoOlds);
```
#### 4.枚举类型转换
##### 4.1 枚举和枚举映射
```JAVA
// AgeEnum
package com.fjg.mapstructdemo.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum AgeEnum {
/**
* 年龄
*/
ZERO("0", "100"),
ONE("1", "18"),
TWO("2", "40"),
THREE("3", "81");
private final String code;
private final String desc;
}
// NameEnum
package com.fjg.mapstructdemo.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum NameEnum {
/**
* 名字
*/
ZERO("0", "未知"),
ONE("1", "张三"),
TWO("2", "李四"),
THREE("3", "王五");
private final String code;
private final String desc;
}
// 转换类
package com.fjg.mapstructdemo.convert;
import com.fjg.mapstructdemo.enums.AgeEnum;
import com.fjg.mapstructdemo.enums.NameEnum;
import org.mapstruct.*;
@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
public interface NameEnumConvert {
/**
* 转换
*
* @param ageEnum 年龄枚举
* @return {@link NameEnum }
*/
@ValueMappings({
@ValueMapping( source = MappingConstants.NULL, target = "ONE" ),
@ValueMapping( source = "THREE", target = MappingConstants.NULL ),
@ValueMapping( source = MappingConstants.ANY_REMAINING, target = "THREE" )
})
NameEnum convert(AgeEnum ageEnum);
}
```
###### 说明:
1.@ValueMapping( source = MappingConstants.NULL, target = "ONE" ),表示如果ageEnum为null则返回AgeEnum.ONE
2.@ValueMapping( source = "THREE", target = MappingConstants.NULL),表示如果传入AgeEnum.THREE,则返回null
3.@ValueMapping( source = MappingConstants.ANY_REMAINING, target = "THREE" ),表示默认返回NameEnum.THREE
##### 4.2枚举和字符串映射
```JAVA
/**
* 转换为str
*
* @param ageEnum 年龄枚举
* @return {@link String }
*/
@ValueMappings({
@ValueMapping( source = MappingConstants.NULL, target = "ONE" ),
@ValueMapping( source = "THREE", target = "THREE" ),
@ValueMapping( source = "ONE", target = "ONE" ),
@ValueMapping( source = "TWO", target = "TWO" ),
@ValueMapping( source = MappingConstants.ANY_UNMAPPED, target = "ZERO" )
})
String convertToStr(AgeEnum ageEnum);
@InheritInverseConfiguration
@ValueMapping(source = MappingConstants.ANY_REMAINING, target = "ZERO")
AgeEnum convertToStr(String nameEnum);
```
###### 说明:
1.**MappingConstants.ANY_UNMAPPED**用于返回字符串,**MappingConstants.ANY_REMAINING**用于返回枚举
##### 4.3自定义名称转换
```JAVA
// CustomEnum
package com.fjg.mapstructdemo.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum CustomEnum implements BaseEnum {
/**
* 自定义枚举
*/
ONE("1", "张三"),
TWO("2", "李四"),
THREE("3", "王五");
private final String code;
private final String desc;
}
// CustomStateEnum
package com.fjg.mapstructdemo.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum CustomStateEnum implements BaseEnum {
/**
* 自定义枚举
*/
ONE_STATE("1", "张三"),
TWO_STATE("2", "李四"),
THREE_STATE("3", "王五");
private final String code;
private final String desc;
}
// 转换类
package com.fjg.mapstructdemo.convert;
import com.fjg.mapstructdemo.enums.CustomEnum;
import com.fjg.mapstructdemo.enums.CustomStateEnum;
import org.mapstruct.EnumMapping;
import org.mapstruct.Mapper;
import org.mapstruct.MappingConstants;
@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
public interface CustomEnumConvert {
/**
* 转换
*
* @param customStateEnum 自定义状态枚举
* @return {@link CustomEnum }
*/
@EnumMapping(nameTransformationStrategy = MappingConstants.STRIP_SUFFIX_TRANSFORMATION, configuration = "_STATE")
CustomEnum convert(CustomStateEnum customStateEnum);
}
```
###### 说明:
1.@EnumMapping的策略
a.MappingConstants.SUFFIX_TRANSFORMATION (添加源后缀)
b.MappingConstants.STRIP_SUFFIX_TRANSFORMATION (删除源后缀)
c.MappingConstants.PREFIX_TRANSFORMATION(添加源前缀)
d.MappingConstants.STRIP_PREFIX_TRANSFORMATION(删除源前缀)