Spring Boot 项目中如何使用MapStruct 1.5.5呢?

林欢喜 Java经验 发布时间:2026-01-17 10:14:18 阅读数:1070 1
下文笔者讲述SpringBoot中使用MapStruct的简介及示例说明,如下所示

MapStruct简介

MapStruct是一个代码生成器
    它能根据你定义的接口自动生成类型安全Bean 映射代码
     避免手动编写大量 `set/get` 代码
    使用步骤主要分为:添加依赖、定义映射接口、配置插件(Maven/Gradle)、使用映射器。
============================================================
   从她的功能上看,我们发现她非常像Lombok

MapStruce详细实现步骤

 1. 添加依赖(以 Maven 为例)
在`pom.xml`中
    添加MapStruct 核心依赖和注解处理器依赖
     注意1.5.5版本需要匹配对应的处理器版本 

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <!-- 其他基础配置 -->
    
    <properties>
        <!-- 定义 MapStruct 版本,方便统一管理 -->
        <mapstruct.version>1.5.5.Final</mapstruct.version>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <!-- MapStruct 核心依赖 -->
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>${mapstruct.version}</version>
        </dependency>
        
        <!-- Spring Boot 核心依赖(基础) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        
        <!-- 测试依赖(可选) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>${maven.compiler.source}</source>
                    <target>${maven.compiler.target}</target>
                    <annotationProcessorPaths>
                        <!-- MapStruct 注解处理器 -->
                        <path>
                            <groupId>org.mapstruct</groupId>
                            <artifactId>mapstruct-processor</artifactId>
                            <version>${mapstruct.version}</version>
                        </path>
                        <!-- 如果使用 Lombok,需要添加 Lombok 处理器(顺序很重要) -->
                        <path>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                            <version>1.18.30</version>
                        </path>
                        <path>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok-mapstruct-binding</artifactId>
                            <version>0.2.0</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

相关说明

 
- `mapstruct` 是核心依赖,运行时需要;
- `mapstruct-processor` 是注解处理器,
      编译时生成映射代码,
      必须放在 `annotationProcessorPaths` 中;
- 当和Lombok 一起使用
     需要添加`lombok-mapstruct-binding` 解决兼容性问题
      且Lombok处理器要在 MapStruct 之后。

定义待映射实体类和 DTO

 
// 实体类
public class User {
    private Long id;
    private String userName;
    private Integer age;
    private LocalDateTime createTime;
    
    // 省略 getter/setter/toString
}

// DTO 类
public class UserDTO {
    private Long id;
    private String name; // 和实体类的 userName 字段名不一致
    private Integer age;
    private String createTime; // 类型不一致(LocalDateTime -> String)
    
    // 省略 getter/setter/toString
}

3. 定义MapStruct 映射接口

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

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

// componentModel = "spring" 表示生成的实现类会被 Spring 管理,可通过 @Autowired 注入
@Mapper(componentModel = "spring")
public interface UserMapper {

    // 如果 componentModel 不是 spring,可通过 Mappers 获取实例
    // UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);

    // 基础映射:字段名一致的自动映射,不一致的用 @Mapping 指定
    @Mapping(source = "userName", target = "name") // 字段名映射
    @Mapping(source = "createTime", target = "createTime", qualifiedByName = "localDateTimeToString") // 自定义类型转换
    UserDTO userToUserDTO(User user);

    // 自定义类型转换方法(Named 注解指定名称,配合 qualifiedByName 使用)
    @Named("localDateTimeToString")
    default String localDateTimeToString(LocalDateTime localDateTime) {
        if (localDateTime == null) {
            return null;
        }
        return localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }

    // 反向映射(DTO -> 实体)
    @Mapping(source = "name", target = "userName")
    @Mapping(source = "createTime", target = "createTime", qualifiedByName = "stringToLocalDateTime")
    User userDTOToUser(UserDTO userDTO);

    @Named("stringToLocalDateTime")
    default LocalDateTime stringToLocalDateTime(String timeStr) {
        if (timeStr == null || timeStr.isEmpty()) {
            return null;
        }
        return LocalDateTime.parse(timeStr, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }
}

关键代码说明

- `@Mapper`:
       标记这是 MapStruct 映射接口,
         `componentModel = "spring"` 是核心配置,
       让映射器被 Spring 托管;
- `@Mapping`:
       指定单个字段的映射规则,
        `source` 是源字段,
       `target` 是目标字段;
- `@Named`:
       给自定义转换方法命名,
       配合 `qualifiedByName` 使用,
       处理类型不一致的映射;
- 接口中的默认方法(default)
       可以编写自定义的转换逻辑

在Spring Boot中使用映射器

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.commandlinerunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.time.LocalDateTime;

@SpringBootApplication
public class MapStructDemoApplication implements CommandLineRunner {

    // 注入 MapStruct 生成的映射器实现类
    @Autowired
    private UserMapper userMapper;

    public static void main(String[] args) {
        SpringApplication.run(MapStructDemoApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        // 1. 构建测试实体
        User user = new User();
        user.setId(1L);
        user.setUserName("张三");
        user.setAge(25);
        user.setCreateTime(LocalDateTime.now());

        // 2. 实体 -> DTO
        UserDTO userDTO = userMapper.userToUserDTO(user);
        System.out.println("实体转DTO:" + userDTO);

        // 3. DTO -> 实体
        User newUser = userMapper.userDTOToUser(userDTO);
        System.out.println("DTO转实体:" + newUser);
    }
}

测试

运行项目后,控制台会输出:

实体转DTO:UserDTO{id=1, name='张三', age=25, createTime='2026-01-17 15:30:00'}
DTO转实体:User{id=1, userName='张三', age=25, createTime=2026-01-17T15:30:00}

注意事项

1. 编译时MapStruct 会
      在`target/generated-sources/annotations` 目录下生成映射器的实现类
       (如 `UserMapperImpl`)
        可以查看生成的代码确认映射逻辑;
2. 当字段名和类型都一致
      无需手动写`@Mapping`,
       MapStruct 会自动映射;
3. 1.5.5 版本兼容 JDK 8+,
      如果使用更高版本 JDK,需确保依赖版本匹配;
4. IDEA 中如果提示映射器注入失败,
     可运行`Maven -> Clean -> Compile` 重新生成实现类
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

本文链接: https://www.Java265.com/JavaJingYan/202601/17686161158539.html

最近发表

热门文章

好文推荐

Java265.com

https://www.java265.com

站长统计|粤ICP备14097017号-3

Powered By Java265.com信息维护小组

使用手机扫描二维码

关注我们看更多资讯

java爱好者