Z次元
文章 笔记 日志
专题
专栏分类 文章归档
友链
友情链接 朋友圈
留言
头像
系列文章
使用Mapstruct轻松实现实体类转换
系列文章
知识积累
最后更新:2024/12/15|创建时间:2024/3/1
文章摘要
这篇文章介绍了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依赖的前面。

版权声明
本文依据 CC-BY-NC-SA 4.0 许可协议授权,请您在转载时注明文章来源为 Z次元 ,若本文涉及转载第三方内容,请您一同注明。
更多专栏文章推荐
知识积累
人非生而知之者,孰能无惑?惑而不从师,其为惑也,终不解矣。
后端传递Long类型数值,前端接收精度丢失(失真)问题
2023/9/20
Docker——容器化部署(进阶篇)
2023/7/22
SpringBoot集成轻量级搜索引擎——Meilisearch
2025/8/7
JDK新版特性(18-21)
2025/2/7
评论区

删除确认

评论删除后无法恢复,请确认是否继续?
发表评论
删除 编辑 回复
钟

1

钟意2024年9月14日

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

删除 编辑 回复
十

2

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

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

前言
引入依赖
快速使用
后记
其它问题
目录
前言
引入依赖
快速使用
后记
其它问题
博客
文章 笔记 日志
专题
专栏分类 文章归档
友链
友情链接 朋友圈
交流
留言 关于我
主页
菜单
置顶
主题
我的
十玖八柒
每天进步多一点
欢迎到访φ(゜▽゜*)♪
最新评论
个人占星:
DeepSeek没有想象中的好用
个人占星:
想给自己的网站弄个统计功能,但不会弄,头疼
永恒末匕:
好哇塞,这个厉害
十玖八柒:
测试图片发送
我的
关于我
个人主页
站点地图
RSS订阅
导航
十年之约
虫洞穿梭
开源博客
前端开源仓库
后端开源仓库
©2020 - 2025 By 十玖八柒 版权所有
豫ICP备20021466号