Z次元

这篇文章介绍了MapStruct,一个用于简化Java实体类转换的注解处理器。它通过@Mapper和@Mapping注解实现VO和DTO之间的转换。文章提供了示例代码。还讨论了常见错误及其解决方法,如Lombok版本问题和重复依赖。总体而言,MapStruct有效地提高了实体类转换的效率。

前言

MapStruct是一个Java编译器插件的注解处理器,可以快速便捷的实现实体类的转换。比如VO和DTO之间的互转。

官网

引入依赖

最新版本号可以去官网获取

        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>${org.mapstruct.version}</version>
        </dependency>
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct-processor</artifactId>
            <version>${org.mapstruct.version}</version>
        </dependency>

快速使用

创建一个接口,作为MapStruct构建的接口。

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;

import java.util.List;

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


    CategoryVO category2VO(Category category);

    /**
     * 如果转换前后的实体类参数不同,可以通过@Mapping注解指定对于的映射关系
     * source表示源对象的属性,及形参中的Category对象的属性
     * target表示目标对象的属性,及转换后的CategoryDTO对象中的属性
     */
    @Mapping(source = "name", target = "displayName")
    CategoryDTO category2DTO(Category category);

    /**
     * 对于List也是可以直接实现转换
     */
    @Mapping(source = "name", target = "displayName")
    List<CategoryDTO> categories2DTO(List<Category> categories);

}

实体类示例:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Category {
    private Long id;
    private String name;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CategoryVO {
    private Long id;
    private String name;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CategoryDTO {
    private Long id;
    private String displayName;
}

需要注意的是MapStruct会在项目构建时自动生成实现类:

图片

测试:

    @Test
    void contextLoads() {
        Category category = new Category(999L, "ahzoo");
        Category category2 = new Category(9L, "十玖八柒");
        ArrayList<Category> list = new ArrayList<>();
        list.add(category);
        list.add(category2);
        CategoryDTO categoryDTO = CategoryMapping.INSTANCE.category2DTO(category);
        CategoryVO categoryVO = CategoryMapping.INSTANCE.category2VO(category);
        List<CategoryDTO> categoryDTOS = CategoryMapping.INSTANCE.categories2DTO(list);
        System.out.println(categoryDTO);
    }

图片

后记

报错:No property named “XXX“ exists in source parameter(s). Did you mean “null“?

原因及解决方式:项目中使用了较低版本的Lombok,升级Lombok版本即可

报错:Couldn’t retrieve @Mapper annotation

原因及解决方式:mapstruct包重复引入,检查其它依赖包中是否含有mapstruct依赖,排除掉重复的依赖包即可。

其它问题

实体类转换后,属性为null

打开编译后的实现类文件,可以发现实现类中只使用new创建了一个对象,却并未对属性赋值,所以转换后的对象是个空的对象:

图片

原因及解决方法:项目中引入了Lombok依赖,需要将Lombok依赖放在MapStruct依赖的前面。

评论区
回复

1

钟意9月14日

这个确实好用,用了很久。博主你夜间时候输入框打字看不见

回复

2

十玖八柒 博主 @钟意9月14日

晕 还真是,这个bug等下次时更新再修复吧

目录