MapStruct 实现 Java Bean 映射
使用纯 Java 的方法调用源对象和目标对象之间进行映射,并非 Java 反射机制,所以性能最好。

介绍

项目中遇到数据库返回的字段不想全部返回给前端,一个一个 setter 挺麻烦,不够优雅。市面上有挺多映射框架如 DozerOrikaMapStructModelMapperJMapper 等,其中 MapStruct 只是代码生成器,使用纯 Java 的方法调用源对象和目标对象之间进行映射,并非 Java 反射机制,所以其性能最好。

实现

Maven 依赖

...
<properties>
    <org.mapstruct.version>1.3.1.Final</org.mapstruct.version>
</properties>
...
<dependencies>
    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct</artifactId>
        <version>${org.mapstruct.version}</version>
    </dependency>
</dependencies>
...
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <annotationProcessorPaths>
                    <path>
                        <groupId>org.mapstruct</groupId>
                        <artifactId>mapstruct-processor</artifactId>
                        <version>${org.mapstruct.version}</version>
                    </path>
                </annotationProcessorPaths>
            </configuration>
        </plugin>
    </plugins>
</build>
...

如果项目中有用到 lombok 的话,MapStruct 也支持,添加如下即可。

<annotationProcessorPaths>
    <path>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>${lombok.version}</version>
    </path>
</annotationProcessorPaths>

普通调用

MapStruct 定义非常简单,因为它完全基于代码生成。

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;

@Mapper
public interface MapStructConverter {
    MapStructConverter MAPPER = Mappers.getMapper(MapStructConverter.class);
 
    @Mapping(source = "status", target = "orderStatus")
    @Override
    Order convert(SourceOrder sourceOrder);
 
    @Override
    DestinationCode convert(SourceCode sourceCode);
}

调用也很简单。

DestinationCode destinationCode = MapStructConverter.MAPPER.convert(sourceCode);

Spring 注解调用

Spring 项目的话可以如下参数实现依赖注入。

@Mapper(componentModel = "spring")
public interface MapStructConverter {
}

@Autowired 注入调用更方便。

@Autowired
private MapStructConverter mapStructConverter;

DestinationCode destinationCode = mapStructConverter.convert(sourceCode);

尾巴

其实这个问题困扰我很久了,之前一直想着用多态方式实现,没找到解决方法后也就用一个一个 setter 方式实现,现在想来很懒,以后还是多思考,多找找轮子,尽可能少写垃圾代码。

参考:


Last modified on 2020-08-21