mapstruct + springboot3 快速整合

一、前言

相信在开发过程中大家都有过对象转换的经验,DO、VO、DTO 之间相互转换,当然你可以最传统的方式,new 一个对象,然后使用 set方法赋值,其实我开发过程中这种方式用的比较多,借助于插件,也不是很麻烦,这种方式的好处在于完全可控,出现 bug 也很容易发现。但是有时候偷懒也会使用 BeanUtils 通过 copy 完成对象创建,这个图省事的时候会用一下,但是这个有个问题就是如果字段名称不一样会导致意想不到的bug,所以在使用的时候要注意字段匹配,慎用。网上大多以性能为由吐槽这种方式,其实我并能没有直观的感受,在一些中小型的项目中只要使用得当,我觉得完全没有问题。我个人认为还是自己手写 **set方法 **最好。**大道至简。**但是本着学习的态度,使用 mapStruct 尝尝鲜。

二、快速整合

2.1 MapStruct 是什么?

首先看一下官方文档:https://mapstruct.org/

学习一门新的技术,官网是最权威的地方。

简单总结一下,就是说 MapStruct 是一个代码生成器,基于约定大于配置的方法,简化了 Java bean 之间的转换过程,因为使用了简单的方法调用,所以速度更快,更加安全。

目的在于解决对象转换的重复工作,以及可能出现错误,与其他框架相比是在编译时生成 bean 映射,确保了高性能,并且错误易于被发现。

易于整合,通过注解的方式使用,侵入性较低。

2.2 快速上手

如果有疑问,建议参考官方文档 https://mapstruct.org/documentation/installation/

2.2.1 引入依赖

  ...
  <properties>
      <org.mapstruct.version>1.6.2</org.mapstruct.version>
  </properties>
  ...
  <dependencies>
      <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.1</version>
              <configuration>
                  <source>1.8</source> <!-- depending on your project -->
                  <target>1.8</target> <!-- depending on your project -->
                  <annotationProcessorPaths>
                      <path>
                          <groupId>org.mapstruct</groupId>
                          <artifactId>mapstruct-processor</artifactId>
                          <version>${org.mapstruct.version}</version>
                      </path>
                      <!-- other annotation processors -->
                  </annotationProcessorPaths>
              </configuration>
          </plugin>
      </plugins>
  </build>

2.2.2 引入插件

我这里使用的是当前最小版本,使用说明: https://mapstruct.org/documentation/stable/reference/html/#introduction

注意官网明确说明当前版本必须使用 jdk9 或以上版本,如果使用的是8,自己降低一下版本,使用上应该查一下不大。

安装一下官方提供的插件,可以进行跳转等一些快捷操作

2.2.3 定义mapper

这里要注意和mybatisPlusmapper区分。

为了便于管理,我在 mapper 下新建了一个文件夹用于存放 mapStructmapper

  • 创建 UserMapper
public interface UserMapper {

    UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);

    AdminUser UserCreateDTO2User(UserCreateDTO userCreateDTO);
}
  • 添加注解(注意区分)

如果转换传入对象和返回对象字段一一对应,那么这样就可以了,如果有不一致的情况,我们可以通过注解手动去指定,@Mapping(target = “manufacturer”, source = “make”) ,还是比较方便的。

  • 测试使用
public static void main(String[] args) {
        UserCreateDTO userCreateDTO = new UserCreateDTO();
        userCreateDTO.setUsername("aaaa");
        userCreateDTO.setPassword("12312432");
        userCreateDTO.setNickname("asdsfd");

        UserMapper userMapper = UserMapper.INSTANCE;
        AdminUser adminUser = userMapper.UserCreateDTO2User(userCreateDTO);
        System.out.println(adminUser.toString());
    }

可以看到如我们预期那样

2.2.4 编译时生成

这个时候我们看一下之前创建的 mapper

可以看到这里提示给我们生成了一个实现类,点进去看一下。

其实底层就是通过最原始的方法,生成了一个转换方法,只不过他是在编译器完成的,这样他既保留我们使用原始方法时候的优势,也帮我们节省了写重复代码的时间,到这里似乎理解了,效率高的原因。

而且当存在一些风险的时候,IDEA 会给予我们一些提示。

2.2.5 一些其它功能

这里我就不一一介绍了,功能有很多,用到的时候再去查文档就可以了。

  • 支持不同属性之间赋值
  • 支持引用对象赋值
  • 支持多转一,多个对象合并成一个
  • 支持赋值时设置默认属性值
  • 支持日期格式化

三、总结

很多文章都喜欢“捧一踩一“,我觉得只有适合自己的才是最好的,就目前体验来说,确实可以给我们节省一些时间,并且使用体验上来说确实很好,在原始方法和属性拷贝之间找到了一个平衡点,更容易被接受,而且上手也很方便,先使用一段时间看看,后续可能会碰到一些问题,再补充。

### 如何在Spring Boot项目中集成和使用MapStruct #### 集成MapStructSpring Boot项目的步骤说明 为了实现对象之间的自动映射功能,可以借助 MapStruct 工具来简化开发过程。以下是关于如何将 MapStruct 集成到 Spring Boot 项目中的具体方法。 #### 添加依赖项 首先,在 `pom.xml` 文件中引入必要的 Maven 或 Gradle 依赖项以支持 MapStruct 功能: ```xml <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct</artifactId> <version>1.5.3.Final</version> <!-- 版本号可能随时间更新 --> </dependency> <!-- 如果您正在使用 annotation processor 来生成代码,则还需要添加以下插件 --> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>17</source> <!-- 使用的 JDK 版本 --> <target>17</target> <annotationProcessorPaths> <path> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>1.5.3.Final</version> </path> </annotationProcessorPaths> </configuration> </plugin> </plugins> </build> ``` 上述配置会确保编译器能够识别并处理由 MapStruct 定义的对象映射接口[^4]。 #### 创建Mapper接口 定义一个简单的 Mapper 接口用于指定源类与目标类之间字段的转换逻辑。例如: 假设存在两个实体类 `UserEntity` 和 DTO 类型 `UserDto`,可以通过如下方式创建它们之间的映射关系: ```java import org.mapstruct.Mapper; import org.mapstruct.Mapping; @Mapper(componentModel = "spring") // 将此 mapper 注册为 Spring Bean public interface UserMapper { @Mapping(source = "name", target = "userName") UserDto userToDto(UserEntity entity); @Mapping(source = "userName", target = "name") UserEntity dtoToUser(UserDto dto); } ``` 这里的关键在于通过 `@Mapper` 注解声明该接口属于 Spring 的组件模型,并允许其被注入到其他服务层或控制器中作为依赖项使用[^5]。 #### 自动生成实现类 当构建项目时(如运行 mvn clean install),Maven 插件将会基于上面定义好的接口自动生成对应的实现类文件。这些生成后的代码通常位于目标目录下的 `/generated-sources/annotations` 路径下。 #### 在业务场景中应用 最后一步是在实际的应用程序里调用这个已经完成初始化工作的 Mapper 实例来进行数据传输操作。比如在一个典型的 RESTful API 中可能会这样写: ```java @RestController @RequestMapping("/users") public class UserController { private final UserService userService; private final UserMapper userMapper; public UserController(UserService userService, UserMapper userMapper){ this.userService = userService; this.userMapper = userMapper; } @GetMapping("/{id}") public ResponseEntity<UserDto> getUserById(@PathVariable Long id) { Optional<UserEntity> optionalUser = userService.findById(id); if (optionalUser.isPresent()) { return new ResponseEntity<>(userMapper.userToDto(optionalUser.get()), HttpStatus.OK); } else { throw new ResourceNotFoundException("Cannot find user with ID:" + id); } } } ``` 以上展示了如何利用 MapStruct 提供的功能快速高效地解决不同领域模型间的数据传递需求问题[^6]。 --- ####
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

曹申阳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值