推荐一个 Java 实体映射工具 MapStruct


2 观看次数
468 字数
0 评论

背景

在一个成熟可维护的工程中,细分模块后,domian工程最好不要被其他工程依赖,但是实体类一般存于domain之中,这样其他工程想获取实体类数据时就需要在各自工程写model,自定义model可以根据自身业务需要而并不需要映射整个实体属性。
mapstruct这个插件就是用来处理domin实体类与model类的属性映射,定义mapper接口,mapstruct就会自动的帮我们实现这个映射接口,避免了麻烦复杂的映射实现。
通过类似下面的代码声明一个Mapper,MapStruct会在编译时自动生成实现代码。除了基本的功能外,MapStruct提供很多高级的功能,全面支持业务中可能出现各种映射要求。示例代码如下

如何使用?

  • 1.简单封装
@Mapper
public interface ContentConverter {
    ContentConverter INSTANCE = Mappers.getMapper(ContentConverter.class);

    @Mappings({
            @Mapping(source = "status", target = "statusVo"),
            @Mapping(source = "isRemove", target = "isRemoveVo"),
            @Mapping(source = "urlImg", target = "imgUrl"),
            @Mapping(source = "onDate", target = "onDateVo"),
    })
    Content.ContentVo domain2dto(Content content);

    List<Content.ContentVo> domains2dto(List<Content> content);

简要说明如下
1 - 用Mapper注解标注Mapper接口(也可以是抽象类)
2 - 可以调用其他的Mapper,来转换复杂类型的字段
3 - 可以指定一个Decorator类对Mapper实现做定制
4 - 常用的practice:声明一个静态的INSTANCE,便于调用方引用
5 - 同名的字段会自动映射,不同名的通过Mapping注解指定映射关系和映射方法
6 - 嵌套对象映射,映射到字段的成员,或成员的成员等
7 - 通过源类型和目标类型不能确定mapper的情况下,可以给mapping方法命名,在使用的时候指定特定名字的mapping方法
8 - 用constant来指定映射为一个常量值
9 - 用@MappingTarget注解指定update方法的参数中代表目标对象的参数
10 - 通过@InheritConfiguration重用映射配置,避免重复配置
  • 2.整合进Maven
<properties>
        <java.version>1.8</java.version>
        <mapstruct.version>1.3.1.Final</mapstruct.version>
</properties>
<!--mapstruct-->
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct-jdk8</artifactId>
            <version>${mapstruct.version}</version>
        </dependency>
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct-processor</artifactId>
            <version>${mapstruct.version}</version>
        </dependency>
  • 3.为Maven compile plugin设置annotation processor(本文使用lombok)
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.6.0</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                            <version>${lombok.version}</version>
                        </path>
                        <path>
                            <groupId>org.mapstruct</groupId>
                            <artifactId>mapstruct-processor</artifactId>
                            <version>${mapstruct.version}</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
  • 4.maven 编译会生成该接口的实现类
  • 5.演示示例
    public static void main(String[] args) {
        Content content = Content.builder()
                .status(true)
                .urlImg("test")
                .rank(4.30)
                .isRemove(false)
                .build();
        Content.ContentVo contentVo = ContentConverter.INSTANCE.domain2dto(content);
        System.out.println(contentVo);
    }
  • 5.结果

    Content.ContentVo(statusVo=true, isRemoveVo=false, imgUrl=test, onDateVo=null, rank=4.3)

另外有一份网友测试对象拷贝工具的测试:https://juejin.im/post/5f05d26df265da23020a847c


评论区

还没有人评论

添加新评论