【Java】使用 MapStruct 实现对象映射

前言

在 Java 开发中,尤其是在使用 Spring 或其他企业级框架时,经常会面临对象之间的转换。常见的场景包括:DTO(数据传输对象)与实体对象之间的转换,或者不同层次之间的对象转换。例如,将数据库实体(Entity)转换成视图层的数据传输对象(DTO),或者将 API 请求参数映射到 Java 对象。

传统的方式是手动编写转换逻辑,但随着项目的复杂性增加,手动编写这些映射代码不仅容易出错,而且繁琐。为了解决这个问题,我们可以使用 MapStruct,一个高效的 Java Bean 映射工具,它提供了一种简单、自动化的方式来完成对象之间的转换。


1.什么是 MapStruct

MapStruct 是一个编译时的代码生成器,它用于 Java Bean 之间的映射。MapStruct 使用注解处理器生成映射代码,因此它非常高效,不会在运行时产生性能开销。它的优势在于:

  • 类型安全:MapStruct在编译时生成映射代码并进行类型检查,如果源对象和目标对象的属性不匹配,会在编译阶段就报错。

  • 性能优秀:由于MapStruct在编译时就生成了映射代码,运行时无需通过反射进行属性拷贝,因此性能较高。

  • 灵活性:MapStruct支持复杂的映射,如嵌套映射、集合映射、自定义转换规则等。

  • 简洁性:MapStruct使用注解来定义映射规则,使得映射规则的定义更加直观和简洁。

  • 无依赖:MapStruct不依赖于任何第三方库,可以很容易地集成到任何项目中。

  • 集成Spring:MapStruct也可以与Spring框架集成,允许在映射器中注入Spring管理的bean。


2.在项目中使用 MapStruct

2.1 引入 MapStruct 依赖

<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct</artifactId>
    <version>1.5.0.Final</version>
</dependency>

2.2 创建 MapStruct 映射接口

假设我们有一个简单的用户实体类和一个用户 DTO。

@Data
public class UserEntity {
    private Long id;
    private String firstName;
    private String lastName;
    private String email;

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

}

定义一个接口,用于描述实体类和 DTO 之间的映射关系。这个接口使用 MapStruct 提供的 @Mapper 注解来标识

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;

@Mapper
public interface UserConvert {

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

    @Mapping(source = "firstName", target = "fullName") // 映射字段
    UserDTO userEntityToUserDTO(UserEntity userEntity);
    
}


3.使用 MapStruct

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    public UserDTO getUser(Long id) {
        UserEntity userEntity = getById(id);
        UserDTO userDTO = UserConvert.INSTANCE.userEntityToUserDTO(userEntity);
        
        return userDTO;
    }

}

此时,userEntity 中的 firstName 字段实际上就映射到了 userDTO 中的 fullName 中,其他相同名称的字段也同样被映射过去了。


4.MapStruct和BeanUtil.copyProperties对比

特性MapStructBeanUtils.copyProperties
实现原理编译时生成代码运行时使用反射复制字段
性能高效,无反射开销较低,使用反射,性能较差
类型安全性强类型检查,编译时报错没有类型检查,运行时可能报错
自定义映射支持自定义映射、复杂转换仅支持简单字段复制
集成框架与 Spring 等框架无缝集成没有框架集成,需手动管理
适用场景适用于复杂对象映射、大规模应用适用于简单对象映射、小规模应用
  • 如果你的项目中有大量的对象映射需求,尤其是复杂对象之间的转换,MapStruct 是更好的选择,它提供了高性能、类型安全和灵活的自定义映射功能。
  • 如果只是进行简单的对象属性复制,并且对性能要求不高,BeanUtils.copyProperties 由于其简单性可以作为快速实现的工具。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值