首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

MapStruct映射到不可修改的模型类

基础概念

MapStruct 是一个用于生成类型安全且易于使用的对象映射代码的框架。它通过注解处理器在编译时生成映射代码,从而避免了运行时的反射开销。不可修改的模型类通常指的是那些一旦创建后其状态就不能被改变的类,例如使用 final 关键字修饰的类或使用 Collections.unmodifiableList 等方法创建的集合。

相关优势

  1. 类型安全:MapStruct 在编译时生成映射代码,可以在编译阶段发现类型不匹配的问题。
  2. 性能:由于映射代码是在编译时生成的,运行时不需要反射,因此性能较高。
  3. 易于维护:生成的代码结构清晰,易于理解和维护。

类型

MapStruct 支持多种类型的映射,包括基本类型、集合、嵌套对象等。对于不可修改的模型类,MapStruct 可以生成相应的映射代码,确保目标对象也是不可修改的。

应用场景

在需要将一个对象的属性映射到另一个对象的场景中,尤其是当目标对象是不可修改的模型类时,MapStruct 非常有用。例如,在数据传输对象(DTO)和领域模型之间的转换,或者在微服务架构中不同服务之间的数据转换。

遇到的问题及解决方法

问题:为什么 MapStruct 映射到不可修改的模型类时会失败?

原因

  1. 不可修改性约束:如果目标对象是不可修改的,而映射过程中需要修改目标对象的属性,就会导致失败。
  2. 类型不匹配:源对象和目标对象的属性类型不匹配。

解决方法

  1. 确保目标对象的不可修改性:在映射过程中,确保目标对象的属性是不可修改的。可以使用 @Mapping(target = "property", ignore = true) 忽略某些属性,或者使用 @AfterMapping 注解在映射完成后进行必要的处理。
  2. 类型匹配:确保源对象和目标对象的属性类型匹配。如果类型不匹配,可以使用 @Mapping(source = "sourceProperty", target = "targetProperty") 进行显式映射。

示例代码

假设有两个类 SourceTarget,其中 Target 是不可修改的模型类:

代码语言:txt
复制
public class Source {
    private String name;
    private int age;
    // getters and setters
}

public final class Target {
    private final String name;
    private final int age;

    public Target(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // getters
}

使用 MapStruct 进行映射:

代码语言:txt
复制
@Mapper
public interface SourceTargetMapper {
    SourceTargetMapper INSTANCE = Mappers.getMapper(SourceTargetMapper.class);

    @Mapping(target = "name", source = "name")
    @Mapping(target = "age", source = "age")
    Target toTarget(Source source);
}

Target 类中添加一个静态工厂方法:

代码语言:txt
复制
public final class Target {
    private final String name;
    private final int age;

    private Target(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public static Target of(String name, int age) {
        return new Target(name, age);
    }

    // getters
}

修改映射器:

代码语言:txt
复制
@Mapper
public interface SourceTargetMapper {
    SourceTargetMapper INSTANCE = Mappers.getMapper(SourceTargetMapper.class);

    @Mapping(target = "name", source = "name")
    @Mapping(target = "age", source = "age")
    Target toTarget(Source source);

    default Target map(Source source) {
        return Target.of(source.getName(), source.getAge());
    }
}

参考链接

MapStruct 官方文档

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

  • 领券