MapStruct如何使用

发布时间:2022-10-17 13:53:46 作者:iii
来源:亿速云 阅读:170

MapStruct如何使用

目录

  1. 简介
  2. MapStruct的优势
  3. 安装与配置
  4. 基本用法
  5. 高级用法
  6. 常见问题与解决方案
  7. 总结

简介

MapStruct 是一个基于注解的 Java 对象映射工具,它能够在编译时生成类型安全的映射代码。与传统的反射机制相比,MapStruct 生成的代码更加高效,且易于调试。MapStruct 的主要目标是通过减少样板代码来提高开发效率。

MapStruct的优势

  1. 类型安全:MapStruct 在编译时生成映射代码,因此可以在编译阶段捕获类型错误。
  2. 高效:生成的代码直接调用对象的 getter 和 setter 方法,避免了反射带来的性能开销。
  3. 易于调试:生成的代码是普通的 Java 代码,可以直接在 IDE 中调试。
  4. 灵活性:支持自定义映射逻辑,可以通过注解或自定义方法来实现复杂的映射。

安装与配置

Maven 配置

pom.xml 中添加以下依赖:

<dependencies>
    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct</artifactId>
        <version>1.5.2.Final</version>
    </dependency>
    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct-processor</artifactId>
        <version>1.5.2.Final</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

Gradle 配置

build.gradle 中添加以下依赖:

dependencies {
    implementation 'org.mapstruct:mapstruct:1.5.2.Final'
    annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.2.Final'
}

基本用法

创建映射接口

首先,定义一个映射接口,并使用 @Mapper 注解标记:

@Mapper
public interface CarMapper {
    CarMapper INSTANCE = Mappers.getMapper(CarMapper.class);

    @Mapping(source = "make", target = "manufacturer")
    @Mapping(source = "numberOfSeats", target = "seatCount")
    CarDto carToCarDto(Car car);
}

使用映射接口

在代码中使用映射接口进行对象转换:

Car car = new Car("Toyota", 5);
CarDto carDto = CarMapper.INSTANCE.carToCarDto(car);

自动映射

如果源对象和目标对象的字段名称相同,MapStruct 会自动进行映射,无需额外配置。

@Mapper
public interface UserMapper {
    UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);

    UserDto userToUserDto(User user);
}

高级用法

自定义映射方法

如果某些字段的映射逻辑比较复杂,可以定义一个自定义方法:

@Mapper
public interface CarMapper {
    CarMapper INSTANCE = Mappers.getMapper(CarMapper.class);

    @Mapping(source = "make", target = "manufacturer")
    @Mapping(source = "numberOfSeats", target = "seatCount")
    CarDto carToCarDto(Car car);

    default String mapEngine(Engine engine) {
        return engine.getType() + " " + engine.getHorsepower() + "hp";
    }
}

使用多个源对象

MapStruct 支持从多个源对象映射到一个目标对象:

@Mapper
public interface OrderMapper {
    OrderMapper INSTANCE = Mappers.getMapper(OrderMapper.class);

    @Mapping(source = "customer.name", target = "customerName")
    @Mapping(source = "address.street", target = "street")
    OrderDto orderToOrderDto(Order order, Customer customer, Address address);
}

集合映射

MapStruct 支持集合类型的映射:

@Mapper
public interface CarMapper {
    CarMapper INSTANCE = Mappers.getMapper(CarMapper.class);

    List<CarDto> carsToCarDtos(List<Car> cars);
}

嵌套映射

如果对象中包含嵌套对象,MapStruct 会自动进行递归映射:

@Mapper
public interface PersonMapper {
    PersonMapper INSTANCE = Mappers.getMapper(PersonMapper.class);

    PersonDto personToPersonDto(Person person);
}

使用表达式

MapStruct 支持使用表达式进行映射:

@Mapper
public interface CarMapper {
    CarMapper INSTANCE = Mappers.getMapper(CarMapper.class);

    @Mapping(target = "fullName", expression = "java(car.getMake() + ' ' + car.getModel())")
    CarDto carToCarDto(Car car);
}

使用常量

可以在映射中使用常量:

@Mapper
public interface CarMapper {
    CarMapper INSTANCE = Mappers.getMapper(CarMapper.class);

    @Mapping(target = "country", constant = "USA")
    CarDto carToCarDto(Car car);
}

使用默认值

可以为目标字段设置默认值:

@Mapper
public interface CarMapper {
    CarMapper INSTANCE = Mappers.getMapper(CarMapper.class);

    @Mapping(target = "seatCount", defaultValue = "4")
    CarDto carToCarDto(Car car);
}

使用条件映射

可以根据条件进行映射:

@Mapper
public interface CarMapper {
    CarMapper INSTANCE = Mappers.getMapper(CarMapper.class);

    @Mapping(target = "seatCount", source = "numberOfSeats", conditionExpression = "java(numberOfSeats > 0)")
    CarDto carToCarDto(Car car);
}

使用自定义注解

可以定义自定义注解来实现复杂的映射逻辑:

@Retention(RetentionPolicy.CLASS)
@Mapping(target = "manufacturer", source = "make")
public @interface CarToDto {
}

@Mapper
public interface CarMapper {
    CarMapper INSTANCE = Mappers.getMapper(CarMapper.class);

    @CarToDto
    CarDto carToCarDto(Car car);
}

使用多个映射器

可以将多个映射器组合在一起使用:

@Mapper(uses = {EngineMapper.class, WheelMapper.class})
public interface CarMapper {
    CarMapper INSTANCE = Mappers.getMapper(CarMapper.class);

    CarDto carToCarDto(Car car);
}

使用依赖注入

MapStruct 支持通过依赖注入框架(如 Spring)来管理映射器实例:

@Mapper(componentModel = "spring")
public interface CarMapper {
    CarDto carToCarDto(Car car);
}

使用 MapStruct 与 Lombok

MapStruct 可以与 Lombok 一起使用,但需要确保 Lombok 在 MapStruct 之前处理:

<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.24</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct</artifactId>
        <version>1.5.2.Final</version>
    </dependency>
    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct-processor</artifactId>
        <version>1.5.2.Final</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

常见问题与解决方案

1. 映射器未生成

问题描述:在编译项目时,MapStruct 没有生成映射器实现类。

解决方案: - 确保 mapstruct-processor 依赖已正确配置。 - 确保 IDE 中启用了注解处理器。

2. 映射字段不匹配

问题描述:源对象和目标对象的字段名称不一致,导致映射失败。

解决方案: - 使用 @Mapping 注解显式指定源字段和目标字段的映射关系。

3. 嵌套对象映射失败

问题描述:嵌套对象未正确映射。

解决方案: - 确保嵌套对象的映射器已正确配置。 - 使用 @Mapper(uses = {NestedMapper.class}) 来指定嵌套对象的映射器。

4. 集合映射失败

问题描述:集合类型的字段未正确映射。

解决方案: - 确保集合元素的类型已正确映射。 - 使用 @Mapping 注解显式指定集合元素的映射关系。

5. 自定义映射方法未生效

问题描述:自定义映射方法未正确调用。

解决方案: - 确保自定义方法的签名与映射字段的类型匹配。 - 使用 @Mapping 注解显式指定自定义方法的调用。

总结

MapStruct 是一个功能强大且高效的 Java 对象映射工具,能够显著减少开发中的样板代码。通过本文的介绍,您应该已经掌握了 MapStruct 的基本用法和高级特性。在实际开发中,合理使用 MapStruct 可以大大提高代码的可维护性和开发效率。

推荐阅读:
  1. Java编码辅助工具Mapstruct用法详解
  2. MapStruct实体转换及List转换的方法讲解

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

mapstruct

上一篇:commons-io如何使用

下一篇:C语言数组如何定义与使用

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》