MapStruct ——An annotation processor for generating type-safe bean mappers


bean对象之间的相互映射的工具有不少,比如常见的BeanUtils,dozer,这都基本都是基于反射实现的,但是MapStruct则不同,下面我们就来看看MapStruct的使用方法吧!

MapStruct类似lombok,在编译期生成基于转换规则的 Impl 文件,运行时直接调用 Impl 文件中的函数。所以它的速度是比其他基于反射实现的工具速度要快!!!

代码

1 pom.xml
<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <org.mapstruct.version>1.3.0.Final</org.mapstruct.version>
        <org.projectlombok.version>1.18.8</org.projectlombok.version>
    </properties>

    <dependencies>

        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${org.projectlombok.version}</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <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.0</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>
                        <path>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                            <version>${org.projectlombok.version}</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
        </plugins>
    </build>
2 实体
@Data
public class Source {

    private String name;

    private String alias;

    private Car car;


    @Data
    public static class Car {
        private String color;
    }
}

@Data
public class Target {

    private String name;

    private String anotherName;

    private Car car;


    @Data
    public static class Car {
        private String color;
    }
}
3 转换
@Mapper
public interface SourceConvert {
		
    // field不一致的,可以使用@Mapping来指定映射关系
    @Mapping(source = "alias", target = "anotherName")
    Target sourceToTarget(Source source);

}
4 使用
public class SourceConvertTest {

    SourceConvert sourceConvert = null;

    @Before
    public void init() {
        sourceConvert = Mappers.getMapper(SourceConvert.class);
    }

    @Test
    public void sourceToTarget() {
        Source source = new Source();
        source.setName("jack");
        source.setAlias("mini");

        Source.Car car = new Source.Car();
        car.setColor("black");

        source.setCar(car);

        Target target = sourceConvert.sourceToTarget(source);
      	
        // Target(name=jack, anotherName=mini, car=Target.Car(color=black))
        System.out.println(target);
    }
}

到这转换已经结束。因为MapStruct是在编译期生成基于转换规则 Impl 文件,所以我们是可以看到编译后生成的SourceConvertImpl的,如下:

public class SourceConvertImpl implements SourceConvert {
    public SourceConvertImpl() {
    }

    public Target sourceToTarget(Source source) {
        if (source == null) {
            return null;
        } else {
            Target target = new Target();
            target.setAnotherName(source.getAlias());
            target.setName(source.getName());
            target.setCar(this.carToCar(source.getCar()));
            return target;
        }
    }

    protected Car carToCar(cn.justme.common.Source.Car car) {
        if (car == null) {
            return null;
        } else {
            Car car1 = new Car();
            car1.setColor(car.getColor());
            return car1;
        }
    }
}

所以我们可以很清楚的看到内部转换的逻辑,当转换出现问题时,MapStruct比一些其他工具类更易debug,定位问题。更多功能可以参考官方文档。

5 优势

总结几点优势:

  1. 速度快
  2. 类型安全
  3. 定位问题更方便
  4. Event handling (@BeforeMapping, @AfterMapping

参考:

官网

dozer


文章作者: shiv
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 shiv !
评论
  目录