最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

MapStruct从入门到精通:Java对象映射的终极指南

网站源码admin2浏览0评论

MapStruct从入门到精通:Java对象映射的终极指南

引言

在Java开发中,对象之间的转换(如DTO转Entity、VO转BO)是常见但繁琐的任务。传统的getter/setter方式不仅繁琐且易错,而反射工具BeanUtils.copyProperties()则存在性能问题。MapStruct作为基于注解的代码生成器,提供了编译时类型安全的优雅解决方案。本文将深入解析MapStruct的核心功能与最佳实践。

一、MapStruct核心优势

  • 高性能:编译期生成代码,无反射调用
  • 类型安全:自动校验字段类型和名称匹配,减少低级错误
  • 灵活扩展:支持自定义类型转换、忽略字段、表达式等高级操作
  • 零依赖:仅需注解处理器,无运行时依赖

二、快速入门

1、添加依赖(Maven)

  • 注意lombok依赖不能在MapStruct处理器依赖后面,否则生成代码没有setXxx(无法转换)
代码语言:javascript代码运行次数:0运行复制
<!-- Lombok -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.24</version>
    <scope>provided</scope>
</dependency>

<!-- MapStruct 核心依赖 -->
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct</artifactId>
    <version>1.5.5.Final</version>
</dependency>

<!-- MapStruct 处理器 (让 MapStruct 自动生成转换代码) -->
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-processor</artifactId>
    <version>1.5.5.Final</version>
    <scope>provided</scope><!-- 只在编译时使用,不打包 -->
</dependency>

2、定义实体和DTO

代码语言:javascript代码运行次数:0运行复制
@Data
public class User {
    private Long id;
    private String name;
}

@Data
public class UserDTO {
    private Long id;
    private String name;
}

3、创建Mapper接口

  • @Mapper:标记接口为映射器
  • 编译后,MapStruct自动生成UserConverterImpl类,实现属性复制逻辑
代码语言:javascript代码运行次数:0运行复制
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;

@Mapper // 标记接口为映射器
public interface UserConverter {
	// 获取自动生成的UserConverterImpl实现类
    UserConverter INSTANCE = Mappers.getMapper(UserConverter.class);
	// UserDTO转为User对象
    User toEntity(UserDTO dto);
}

4、使用Mapper

代码语言:javascript代码运行次数:0运行复制
public static void main(String[] args) {
    UserDTO dto = new UserDTO();
    dto.setId(1L);
    dto.setName("xc");

    User user = UserConverter.INSTANCE.toEntity(dto);
    System.out.println(user); // User(id=1, name=xc)
}
  • target编译自动生成实现类相同属性set

三、进阶技巧

1、处理字段名不一致

  • 通过@Mapping注解显式指定源和目标字段
代码语言:javascript代码运行次数:0运行复制
@Data
public class User {
    private Long id;
    private String username;
}

@Data
public class UserDTO {
    private Long id;
    private String name;
}

@Mapper
public interface UserConverter {
    UserConverter INSTANCE = Mappers.getMapper(UserConverter.class);
    
    @Mapping(source = "name", target = "username")
    User toEntity(UserDTO dto);
}

2、集合映射

  • 自动生成ListSet的映射方法
  • List之间不能使用@Mapping,如果有字段不一致,需要添加List的泛型类@Mapping的转换
代码语言:javascript代码运行次数:0运行复制
@Mapper
public interface UserConverter {
    UserConverter INSTANCE = Mappers.getMapper(UserConverter.class);
    
    @Mapping(source = "name", target = "username")
    User toEntity(UserDTO dto);

    List<User> toEntityList(List<UserDTO> users);
}

3、表达式、常量、默认值

  • 根据表达式结果赋值目标属性
  • 生成的目标对象role始终为"admin"常量
  • 若源对象的id为null,目标字段id设为"100L";否则使用源值
代码语言:javascript代码运行次数:0运行复制
@Mapper
public interface UserConverter {
    UserConverter INSTANCE = Mappers.getMapper(UserConverter.class);
    
	@Mapping(target = "status", expression = "java(user.isActive() ? 1 : 0)")
	@Mapping(target = "role", constant = "admin")
    @Mapping(target = "id", defaultValue = "100L")
    User toEntity(UserDTO dto);
}

4、自定义方法

  • 在Mapper中定义默认方法实现复杂逻辑
代码语言:javascript代码运行次数:0运行复制
@Mapper
public interface UserConverter {
    UserConverter INSTANCE = Mappers.getMapper(UserConverter.class);
    
    UserDTO toDTO(User user);

	default UserDTO merge(User user, UserDetails details) {
	    UserDTO dto = toDTO(user);
	    dto.setAge(details.getAge());
	    return dto;
	}
}

4、多Mapper组合

  • 通过uses参数引用其他Mapper
代码语言:javascript代码运行次数:0运行复制
@Mapper(uses = {AddressConverter.class})
public interface UserConverter {
    // 自动调用AddressMapper进行嵌套转换
    UserDTO toDTO(User user);
}

四、与SpringBoot整合

1、配置组件模型

  • 添加componentModel = "spring",通过@Autowired注入Mapper
代码语言:javascript代码运行次数:0运行复制
@Mapper(componentModel = "spring")
public interface UserConverter {
	// 省略不用再写,spring自动生成
    // UserConverter INSTANCE = Mappers.getMapper(UserConverter.class);
    
    UserDTO toDTO(User user);
}

2、依赖注入

代码语言:javascript代码运行次数:0运行复制
@Service
public class UserService {
    
    @Autowired
    private UserConverter userConverter;
    
    public UserDTO getUser(Long id) {
        return userConverter.toDTO(repository.findById(id));
    }
}

总结

MapStruct通过其优雅的设计和强大的功能,显著提升了Java对象映射的效率。结合编译时安全检查和灵活的自定义能力,它是现代Java工程中不可或缺的工具。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2025-04-21,如有侵权请联系 cloudcommunity@tencent 删除接口入门java编译对象
发布评论

评论列表(0)

  1. 暂无评论