MapStruct 入门使用

MapStruct是一个代码生成库,简化了Java对象到Java对象之间的映射过程。通过注解接口,它可以自动生成转换代码,支持多种映射场景,如属性映射、定制方法、目标对象更新等。此外,还支持数据类型转换、嵌套对象映射和使用上下文对象定制转换。在Spring项目中,可通过Maven依赖和配置进行集成。
摘要由CSDN通过智能技术生成

1. 概述

MapStruct 可以将某几种类型的对象映射为另外一种类型,如将多个Domain 对象转换为 DTO,涉及到类似之间对象转换的都可以用它来完成。其主要作用就是:Java bean mappings

详细信息可以参考最新版本的文档:MapStruct 1.3.0.Final Reference Guide

本文的内容也是来源于官方文档,只是简单的做一个简单的说明,方便理解和快速的使用。

2 引入依赖

Spring项目中的简单使用,用Maven管理依赖,在pom文件中引入MapStruct:

		<org.mapstruct.version>1.3.0.Final</org.mapstruct.version>

        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>${org.mapstruct.version}</version>
            <scope>provided</scope>
        </dependency>
		...
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.mapstruct</groupId>
                            <artifactId>mapstruct-processor</artifactId>
                            <version>${org.mapstruct.version}</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
12345678910111213141516171819202122232425

注意,需要jdk1.8以上。

2. 简单使用

2.1 基础mappings

定义Mapper接口

@Mapper 
public interface CarMapper {
    @Mapping(source = "make", target = "manufacturer")     
    @Mapping(source = "numberOfSeats", target = "seatCount")     
    CarDto carToCarDto(Car car);
    
    @Mapping(source = "name", target = "fullName")     
    PersonDto personToPersonDto(Person person);
  }
123456789

2.2 Adding custom methods to mappers

可以使用@context注解,传入对象,起到一定的定制作用。

2.3 多个参数来源的映射

@Mapper 
public interface AddressMapper {
    @Mapping(source = "person.description", target = "description")     
    @Mapping(source = "address.houseNo", target = "houseNumber")    
    DeliveryAddressDto personAndAddressToDeliveryAddressDto(Person person, Address address); 
12345

2.4 更新现有的 bean instances

使用@MappingTarget 传入一个bean,则更新的就是它:

@Mapper 
public interface CarMapper {
    void updateCarFromDto(CarDto carDto, @MappingTarget Car car);
 }
1234

2.5 Mappings with direct field access

MapStruct同样支持没有getter/setter方法的映射。但是要求属性可以直接访问。

2.6 @AfterMapping和@BeforeMapping

在接口中实现这两个注解标注的default方法,会在映射前后调用:

@Mapper(componentModel = "spring")
public interface AddressMapper {

    AddressMapper MAPPER = Mappers.getMapper(AddressMapper.class);

    @Mapping(target = "name", source = "address.name")
    @Mapping(target = "gender", source = "person.gender")
    PersonAddressDto convert(Address address, Person person, @MappingTarget PersonAddressDto target);

    @AfterMapping
    default void afterMapping(Address address, @MappingTarget PersonAddressDto target) {
    }

    @BeforeMapping
    default void beforeMapping(Person person, @MappingTarget PersonAddressDto target) {
    }
}
1234567891011121314151617

其生成的实现类中,会分别生成前置和后置的映射:

@Component
public class AddressMapperImpl implements AddressMapper {

    @Override
    public PersonAddressDto convert(Address address, Person person, PersonAddressDto target) {
        if ( address == null && person == null ) {
            return null;
        }
        //前置
        beforeMapping( person, target );

        if ( address != null ) {
            target.setName( address.getName() );
        }
        if ( person != null ) {
            target.setGender( person.getGender() );
        }
        //后置
        afterMapping( address, target );

        return target;
    }
}
1234567891011121314151617181920212223

4. Retrieving a mapper

4.1 The Mappers factory

org.mapstruct.factory.Mappers class. Just invoke the getMapper() method。

例如:

@Mapper(componentModel = "spring")
public interface AddressMapper {

    AddressMapper MAPPER = Mappers.getMapper(AddressMapper.class);

    @Mapping(target = "name", source = "address.name")
    @Mapping(target = "gender", source = "person.gender")
    PersonAddressDto convert(Address address, Person person);
}
123456789

getMapper方法,相当于从其实现类中new一个无参构造方法,则可以通过它调用对应的方法。

4.2 spring依赖注入

@Mapper#componentModel属性,在定义的接口上加上

@Mapper(componentModel = "spring")
1

会自动生成实现类,并使用@Component注解标注。

5. 数据类型转换

5.1 隐士类型转换

@Mapping注解:numberFormat 、dateFormat

5.2 Controlling nested bean mappings

5.3 Invoking other mappers

使用注解@Mapper(uses=XXX.class)
MapStruct 会从XXX.class中查找满足转化的方法

5.4 Passing the mapping target type to custom mappers

@MappingTarget

5.5 Passing context or state objects to custom methods

在方法中传入对象,借助这个对象来定制转换方法。借助于@Context

5.6 Mapping method selection based on qualifiers

使用qualifiers标志符,选择特定的方法来完成映射。qualifiedBy(class) 、qualifiedByName(使用@Name注解)
@Named:annotating the methods to qualify。可以用在类上和方法上。

根据引用,如果MapStruct找不到映射方法,它将尝试生成一个自动的映射方法来处理源和目标属性之间的映射。这意味着,如果你没有显式地定义映射方法,MapStruct会自动生成一个。 另外,你可以参考引用中的官方文档了解更多关于映射引用对象的信息。该文档提供了详细的指南和示例。 关于在Spring Boot中配置MapStruct,请参考引用中提供的连接。连接中提供了在Gradle文件中配置MapStruct的示例代码。你可以按照这个示例进行配置,并且根据你的具体需求进行相应的调整。 总结起来,如果你在使用MapStruct时遇到找不到映射方法的问题,你可以尝试让MapStruct自动生成映射方法。此外,你可以查阅官方文档以获得更多关于映射引用对象以及在Spring Boot中配置MapStruct的信息。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [MapStruct入门到出门(二)](https://blog.csdn.net/printf_scnaf/article/details/125292697)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [gradle配置mapstruct和jpa](https://blog.csdn.net/qq_23165823/article/details/100541923)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值