最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
MapStruct 中高效移除审计字段重复 @Mapping 注解的最佳实践
时间:2026-07-09 10:07:47 编辑:袖梨 来源:一聚教程网
本文介绍如何通过自定义注解统一忽略 createdat、updatedat、createdby、modifiedby 等审计字段,避免在多个 mapstruct 映射方法中重复书写冗长的 @mapping(target = "...", ignore = true)。
本文介绍如何通过自定义注解统一忽略 createdat、updatedat、createdby、modifiedby 等审计字段,避免在多个 mapstruct 映射方法中重复书写冗长的 @mapping(target = "...", ignore = true)。
在使用 MapStruct 构建 DTO 与实体间映射时,审计字段(如 createdAt、updatedAt、createdBy、modifiedBy)通常由框架或服务层自动填充,不应由映射逻辑覆盖。但若多个映射方法需忽略相同字段(尤其涉及嵌套对象如 parentCategory.createdAt),直接堆叠 @Mapping(target = "...", ignore = true) 不仅代码冗余、易出错,还严重损害可维护性。
MapStruct 支持复合注解(Composed Annotations)——即通过元注解将一组 @Mapping 封装为一个语义化、可复用的自定义注解。这是解决重复映射配置最简洁、类型安全且 IDE 友好的方案。
✅ 步骤一:定义 @IgnoreAuditMapping 自定义注解
import org.mapstruct.Mapping;import java.lang.annotation.*;@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@Mapping(target = "createdAt", ignore = true)@Mapping(target = "updatedAt", ignore = true)@Mapping(target = "createdBy", ignore = true)@Mapping(target = "modifiedBy", ignore = true)public @interface IgnoreAuditMapping {}
⚠️ 注意:该注解必须标注 @Mapping 元素(而非 @Mappings),因为 MapStruct 仅识别单个 @Mapping 作为合法元注解;同时需确保 @Retention(RUNTIME),否则运行时无法解析。
✅ 步骤二:在 Mapper 接口中复用自定义注解
@Mapper(config = MapperConfiguration.class)public interface CategoryMapper { CategoryDto toDto(Category category); @IgnoreAuditMapping @Mapping(target = "id", ignore = true) @Mapping(target = "quizzes", ignore = true) // 嵌套对象审计字段仍需显式声明(因复合注解仅作用于直接属性) @Mapping(target = "parentCategory.createdAt", ignore = true) @Mapping(target = "parentCategory.updatedAt", ignore = true) @Mapping(target = "parentCategory.createdBy", ignore = true) @Mapping(target = "parentCategory.modifiedBy", ignore = true) @Mapping(target = "parentCategory.id", ignore = true) @Mapping(target = "parentCategory.quizzes", ignore = true) Category toCategory(CategoryDto categoryDto); @IgnoreAuditMapping @Mapping(target = "id", ignore = true) @Mapping(target = "quizzes", ignore = true) @Mapping(target = "parentCategory", ignore = true) @Mapping(target = "childCategories", ignore = true) Category toDomain(CategoryCreationRequest request);}
✅ 效果:@IgnoreAuditMapping 自动展开为 4 个 @Mapping(..., ignore = true),显著减少样板代码,提升可读性与一致性。
? 进阶建议:处理嵌套审计字段自动化(可选)
MapStruct 当前不支持自动递归忽略嵌套对象的同名审计字段(如 parentCategory.createdAt)。因此对嵌套结构,仍需手动添加对应 @Mapping。若项目中嵌套层级多且模式固定,可考虑:
- 编写 MapStruct Extension(需实现 ModelElementProcessor)实现自动注入;
- 或结合 Lombok 的 @Builder + 自定义 @Builder.Default 逻辑规避映射需求;
- 更轻量的方式:抽取 @Mapping 列表为常量(非推荐,丧失类型安全与 IDE 支持)。
✅ 总结
| 方案 | 优点 | 缺点 |
|---|---|---|
| ✅ 自定义复合注解(推荐) | 类型安全、IDE 可跳转、零运行时开销、符合 MapStruct 最佳实践 | 需额外定义注解类;嵌套字段仍需手动声明 |
| ❌ 复制粘贴 @Mapping | 无需额外组件 | 维护成本高、易遗漏、违反 DRY 原则 |
| ⚠️ 使用 @InheritInverseConfiguration | 适用于双向映射场景 | 不适用于单向忽略,且无法跨方法复用 |
最终,@IgnoreAuditMapping 不仅解决了审计字段的重复问题,更体现了 MapStruct 对领域语义抽象的支持——让映射逻辑回归业务意图,而非陷入模板化配置泥潭。
相关文章
- 《Disney Lorcana: Wilds Unknown》预购开启 首批《Toy Story》及皮克斯卡牌购买指南 07-29
- 车来了赶车闹钟如何设置 07-29
- 崩坏星穹铁道余晖残卷巨剑守护打法攻略 07-29
- 崩坏星穹铁道砂金角色部分背景介绍 07-29
- 崩坏3雷电芽衣什么时候上线 07-29
- 玩具熊的五夜后宫4代噩梦气球男孩Nightmare Balloon Boy介绍 07-29