------------------------------------------------------------------------------------------
org.mapstruct.Mapper 和 org.mapstruct.Mapping 是 MapStruct 框架中的核心注解,用于实现 Java 对象之间的自动映射。MapStruct 是一个代码生成器,通过注解配置生成类型安全、高性能的对象映射代码,避免手动编写繁琐的 setter/getter 转换逻辑。1. @Mapper 注解
- 作用:标记接口为 MapStruct 映射器,MapStruct 会在编译时为该接口生成实现类,实现对象之间的转换逻辑。
- 常用属性:
componentModel:指定映射器的组件模型,如spring(生成 Spring Bean)、cdi、jsr330等,便于依赖注入。uses:指定其他映射器类,用于处理复杂类型转换。unmappedTargetPolicy:指定未映射目标属性的处理策略(如报错、警告)。
示例:
java
运行
// 声明一个 Spring 管理的映射器
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface UserMapper {// 映射方法(由 MapStruct 自动实现)UserDTO toDTO(User user);User toEntity(UserDTO dto);
}
2. @Mapping 注解
- 作用:配置源对象与目标对象之间的属性映射关系,解决属性名不一致、类型转换等问题。
- 常用属性:
source:源对象的属性名(如userName)。target:目标对象的属性名(如name)。dateFormat:日期类型转换的格式(如yyyy-MM-dd)。expression:通过表达式自定义转换逻辑(如java: java.util.UUID.randomUUID().toString())。ignore:是否忽略该属性映射(true表示不映射)。
示例:
java
运行
@Mapper(componentModel = "spring")
public interface OrderMapper {// 基础映射(属性名一致时可省略 @Mapping)@Mapping(source = "orderNo", target = "orderNumber") // 名称不一致时映射@Mapping(source = "createTime", target = "createDate", dateFormat = "yyyy-MM-dd") // 日期格式化@Mapping(target = "id", ignore = true) // 忽略目标属性OrderDTO toDTO(Order order);// 多源对象映射@Mapping(source = "user.name", target = "userName")@Mapping(source = "order.total", target = "amount")OrderDetailDTO toDetailDTO(User user, Order order);
}
核心优势
- 类型安全:编译时检查属性映射是否正确,避免运行时错误。
- 高性能:生成的代码是普通的
setter/getter调用,比反射(如 BeanUtils)更快。 - 可维护性:映射规则集中在接口注解中,无需手动编写转换工具类。
使用时需在项目中引入 MapStruct 依赖(以 Maven 为例):
xml
<dependency><groupId>org.mapstruct</groupId><artifactId>mapstruct</artifactId><version>1.5.5.Final</version>
</dependency>
<dependency><groupId>org.mapstruct</groupId><artifactId>mapstruct-processor</artifactId><version>1.5.5.Final</version><scope>provided</scope>
</dependency>
通过这两个注解,可快速实现
DO、DTO、VO 等对象之间的转换,大幅简化开发工作。------------------------------------------------------------------------------------------
org.mapstruct.Mapping属性详解
org.mapstruct.Mapping 是 MapStruct 框架中用于精细控制属性映射规则的核心注解,主要解决源对象与目标对象之间属性名不一致、类型不匹配、格式转换等问题。以下是其常用属性的详细说明及示例:1. 基础映射属性
source
- 作用:指定源对象的属性名(即被映射的字段)。
- 适用场景:源与目标属性名不同时,明确源字段。
- 示例:
java运行
// 源对象有属性 userName,目标对象有属性 name @Mapping(source = "userName", target = "name") UserDTO toDTO(User user); - 注意:
- 支持嵌套属性(如
source = "user.addr.city")。 - 若源属性为集合,可通过索引访问(如
source = "hobbies[0]")。
- 支持嵌套属性(如
target
- 作用:指定目标对象的属性名(即接收映射的字段)。
- 必须搭配:通常与
source一起使用,定义映射关系。 - 示例:
java运行
// 源字段 id 映射到目标字段 userId @Mapping(source = "id", target = "userId") OrderDTO toDTO(Order order);
ignore
- 作用:指定是否忽略目标属性(不进行映射)。
- 默认值:
false(不忽略)。 - 适用场景:目标属性无需从源对象获取(如自增 ID、默认值字段)。
- 示例:
java运行
// 忽略目标对象的 createTime 字段(由目标系统自动生成) @Mapping(target = "createTime", ignore = true) UserDTO toDTO(User user);
2. 类型转换属性
dateFormat
- 作用:指定日期 / 时间类型的转换格式(适用于
Date、LocalDate、String之间的转换)。 - 适用场景:源为
Date类型,目标为String类型(或反之)。 - 示例:
java运行
// 源字段 createTime(LocalDateTime)转换为目标字段 createTimeStr(String),格式为 yyyy-MM-dd HH:mm:ss @Mapping(source = "createTime", target = "createTimeStr", dateFormat = "yyyy-MM-dd HH:mm:ss") OrderDTO toDTO(Order order);
numberFormat
- 作用:指定数字类型的格式化规则(如保留小数、百分比等)。
- 适用场景:
Number与String类型转换,需格式化显示。 - 示例:
java运行
// 源字段 price(BigDecimal)转换为目标字段 priceStr(String),保留2位小数 @Mapping(source = "price", target = "priceStr", numberFormat = "#0.00") ProductDTO toDTO(Product product);
qualifiedByName
- 作用:指定自定义转换方法(通过方法名引用),处理复杂类型转换。
- 使用步骤:
- 在映射器接口中定义自定义转换方法,并添加
@Named注解标记。 - 在
@Mapping中通过qualifiedByName引用方法名。
- 在映射器接口中定义自定义转换方法,并添加
- 示例:
java运行
import org.mapstruct.Named;@Mapper(componentModel = "spring") public interface UserMapper {// 引用自定义转换方法 "statusConverter"@Mapping(source = "status", target = "statusDesc", qualifiedByName = "statusConverter")UserDTO toDTO(User user);// 自定义转换方法:将数字状态码转为文字描述@Named("statusConverter")default String convertStatus(Integer status) {if (status == 1) return "正常";if (status == 0) return "禁用";return "未知";} }
expression
- 作用:通过 Java 表达式自定义映射逻辑(直接生成代码)。
- 语法:
expression = "java(表达式)",表达式需返回目标属性类型。 - 适用场景:简单逻辑的动态计算(如生成 UUID、拼接字符串)。
- 示例:
java运行
// 目标字段 orderSn 由表达式生成(UUID + 时间戳) @Mapping(target = "orderSn", expression = "java(java.util.UUID.randomUUID().toString() + System.currentTimeMillis())") OrderDTO toDTO(Order order); - 注意:表达式中需使用完整类名(如
java.util.UUID而非UUID)。
3. 集合与映射属性
collectionMappingStrategy
- 作用:指定集合类型(如
List、Set)的映射策略。 - 可选值:
ACCESSOR_ONLY(默认):通过getter/setter操作集合。SETTER_PREFERRED:优先使用setter方法。ADDER_PREFERRED:优先使用add方法(如addItem())。TARGET_IMMUTABLE:目标集合不可变时,创建新集合。
- 示例:
java运行
// 对 tags 字段使用 ADDER_PREFERRED 策略(调用 addTag() 而非 setTags()) @Mapping(source = "tags", target = "tags", collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED) PostDTO toDTO(Post post);
mapKeyDateFormat / mapValueDateFormat
- 作用:当映射
Map类型时,指定key或value为日期类型的格式化规则。 - 示例:
java运行
// Map<Date, String> 映射为 Map<String, String>,key 格式化为 yyyy-MM-dd @Mapping(target = "dateMap", mapKeyDateFormat = "yyyy-MM-dd") ReportDTO toDTO(Report report);
4. 其他常用属性
defaultValue
- 作用:当源属性为
null时,指定目标属性的默认值。 - 示例:
java运行
// 若 source 中 age 为 null,目标 age 设为 0 @Mapping(source = "age", target = "age", defaultValue = "0") UserDTO toDTO(User user);
defaultExpression
- 作用:当源属性为
null时,通过表达式生成目标属性的默认值(比defaultValue更灵活)。 - 示例:
java运行
// 若 createTime 为 null,默认值为当前时间 @Mapping(source = "createTime", target = "createTime", defaultExpression = "java(java.time.LocalDateTime.now())") UserDTO toDTO(User user);
unmappedSourcePolicy / unmappedTargetPolicy
- 作用:指定源 / 目标属性未被映射时的处理策略(覆盖
@Mapper中的全局配置)。 - 可选值:
IGNORE:忽略(默认)。WARN:编译时警告。ERROR:编译时报错(强制检查,推荐生产环境)。
- 示例:
java运行
// 若目标字段有未映射的属性,编译时报错 @Mapping(target = "extra", unmappedTargetPolicy = ReportingPolicy.ERROR) UserDTO toDTO(User user);
总结:常用属性优先级
当多个属性同时使用时,生效优先级为:
expression > qualifiedByName > dateFormat/numberFormat > 默认转换通过灵活组合这些属性,MapStruct 可应对绝大多数对象映射场景,既保证类型安全,又避免手动编写转换代码的繁琐。
------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------
