说实话,我也不想这么自夸,但不这样说出来,估计你们也不知道,Mapstruct 这玩意儿到底是怎么被我整的、咋滴。别看平时我就是个吊里吧唧的技术混子,今天要是好好聊一聊,我敢说,技术这块儿我真的是个不小的“老油条”了,啥问题都能给你弄个好办法。
开场白,来点儿废话先
其实我们这些开发人员,不就是在写代码么,天天一行一行地加代码,加得都要吐了。但是,细想想,能把简单的事儿搞得不简单,那才是真正的技术。所以,我的这个 Mapstruct 的用法,真心有点东西!你要问我为什么?我就告诉你,Mapstruct 简直是让对象转换这块儿变得无比优雅,别说你没听过,放在平时的开发中,绝对是个神器!
但是啊,怎么用,怎么快速上手,我可得说说,这可不是一上来就能搞明白的玩意儿。搞定了,你得到了的是舒服的代码和快速的效率,没搞定,那就是个烦心事儿,连个简单的 Bean 转换都做不好,天天就知道在 IDE 里点来点去的。
说说我咋入坑的,别急,先别笑
最开始我也是和你们一样,觉得啥 Mapstruct 就是个没啥意思的工具,写 Java 的时候,Bean 和 DTO 之间的转换都是直接手写。你信不信,我还特自豪,自己写的转换简直比任何工具都好,结果呢?一堆重复代码,维护难度飞起,简直就是“千篇一律”,我写得嘴里都能吐出火来。可不是咋滴,你说重复的代码有啥意思?当然,后来我看了别的老大佬都在用 Mapstruct,心想:行吧,你们牛逼,老子也试试,结果——
搞定了!真香!从那时候开始,我就再也没有回头过,大家都知道,我这个人,一旦觉得啥好,就开始偷偷分享,不到三天,办公室就变成了 Mapstruct 学习小组了!
什么是 Mapstruct?简单几句带你上天
好吧,正式进入正题。你要是刚接触这东西,肯定会觉得挺晕的。Mapstruct 其实就是什么?就是一个对象映射框架,别看它名字这么拗口,实际上它比你想的还简单。
Mapstruct 核心作用
Mapstruct 是用来做 Java Bean 之间的转换的,和你自己手写的转换代码比,它可以让你写出更加简洁、清晰的代码。你可能觉得 Java 本来就有 Reflection、Spring 也有 BeanUtils,那为啥还要用它?这就好比你买车不买汽车一样,Mapstruct 就是“官方认证”的高级工具,能让你省下不少不必要的麻烦。它的好处就在于:
-
编译时生成代码,速度快;
-
类型安全,编译器会帮你检查类型;
-
不依赖反射,运行时性能更好;
-
配置简单,几行注解就搞定!
基础使用,开始带你走
好了,不多废话,废话说太多,怕你们觉得我没正事,直接给你们上干货。先给你们写个简单的例子,展示一下基本用法。哎呀,我觉得写这个其实挺带劲儿的,手痒,咱们来点实战。
首先,咱们得引入 Mapstruct 的依赖。还好,我提前准备了:
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.5.2.Final</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.2.Final</version>
<scope>provided</scope>
</dependency>
然后,这个就是最简单的场景了。咱们先有两个类,一个是 User
,一个是 UserDTO
,搞个简单的字段映射:
// 原始 User 类
public class User {
private String name;
private int age;
private String email;
// 省略 getter 和 setter
}
// UserDTO 类
public class UserDTO {
private String fullName;
private int age;
// 省略 getter 和 setter
}
好了,这时候有了这两个类之后,你需要做的就是用 Mapstruct 来映射。这里有个魔法注解,叫 @Mapper
,对,你只需要这么写。
@Mapper
public interface UserMapper {
UserDTO userToUserDTO(User user); // 这里你直接告诉它怎么映射就行
}
这里特别重要:@Mapper
注解的接口,Mapstruct 会在编译时生成实现类。对,你没听错,是编译时生成代码!这比手写代码要强得多,能够避免手动维护每一行映射代码。
完整代码
// User 类
public class User {
private String name;
private int age;
private String email;
// getter 和 setter
}
// UserDTO 类
public class UserDTO {
private String fullName;
private int age;
// getter 和 setter
}
// Mapper 接口
@Mapper
public interface UserMapper {
UserDTO userToUserDTO(User user);
}
// 测试代码
public class MapperTest {
public static void main(String[] args) {
User user = new User();
user.setName("Jack");
user.setAge(30);
user.setEmail("jack@example.com");
// 获取映射实例
UserMapper mapper = Mappers.getMapper(UserMapper.class);
UserDTO userDTO = mapper.userToUserDTO(user);
System.out.println("Name: " + userDTO.getFullName()); // 输出 Jack
System.out.println("Age: " + userDTO.getAge()); // 输出 30
}
}
重点,记住,Mapstruct 自动帮你生成实现类,不需要你手动写什么代码!
真实项目中怎么用?
这玩意儿,光是写点儿简单的 Bean 转换,没啥意思。你要想实现真正的应用,就得在复杂的项目里整了。比如在我们的系统里,有的时候要做从一个实体类到多个 DTO 的转换,那这时候,用 Mapstruct 的多个映射就能让你实现得非常轻松。
比如,我曾经在一个 Spring Boot 项目里,搞了个多层的业务逻辑层,DTO 层和实体类层之间的映射就是这么搞的。没有 Mapstruct,根本想不到这么简单的做法,信不信你都得去用它。
结尾,话唠一下总结下
说了这么多,别说我不提醒你,这 Mapstruct 真心是个提升效率的神器。你们看,我这不是光说不练,给你们看了一堆代码和实战经验。想要用好它,靠的就是不断实践!不要看它简单,不要看它是“写个注解”那么容易,它背后也有它的深度和力量。
所以,看到我的用法,不少同事现在悄悄开始模仿了。放心,我也没不告你,照着我这么写,你能得心应手,搞得比我还溜。