0
点赞
收藏
分享

微信扫一扫

MapStruct详解

1 啥玩意?

MapStruct 是一个代码生成器,它基于约定优于配置的方法极大地简化了 Java bean 类型之间映射的实现。

生成的映射代码使用简单的方法调用,因此速度快、类型安全且易于理解。

2 为什么?

多层应用程序通常要在不同对象模型(如entities和 DTO)之间映射。编写映射代码是乏味易出错任务。 MapStruct 旨在通过尽可能自动化来简化这项工作。

与其他映射框架相比,MapStruct 在编译时生成 bean 映射,这确保高性能,允许快速的开发人员反馈和彻底的错误检查。

3 如何?

MapStruct 是一个注解处理器,它插入到 Java 编译器中,可以在命令行构建(Maven、Gradle 等)以及IDE中使用。

MapStruct 使用合理的默认值,但在配置或实现特殊行为时会妨碍。

4 快速上手

下面演示如何使用 MapStruct 映射两个对象。

4.1 你的两个类

假设我们有一个代表文章的类(例如 JPA 实体)和一个附带的数据传输对象 (DTO):

public class InterviewEntity implements Serializable {
    /**
     * 主键
     */
    @TableId
    private Long id;

    /**
     *
     */
    private Long userId;

    /**
     *
     */
    private String title;

    /**
     *
     */
    private String newTitle;

    /**
     *
     */
    private String content;

    /**
     *
     */
    private String newContent;

    /**
     *
     */
    private String type;

    /**
     *
     */
    private String status;

    /**
     *
     */
    private String hasEdit;

    /**
     *
     */
    private Integer isAnonymousFlag;

    private Integer jobId;

    // 面经分类
    @TableField(exist = false)
    private String careerName;

    /**
     *
     */
    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createAt;

    /**
     *
     */
    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    private Date editTime;

    @TableField(exist = false)
    private static final long serialVersionUID = 1L;
    private Integer pageView;
}
@Data
public class ArticleVO {
    /**
     * 主键
     */
    private String id;

    /**
     * 用户主键
     */
    private Long userId;

    /**
     * 标题
     */
    private String title;


    /**
     * 内容
     */
    private String content;

    /**
     * 创建时间
     */
    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createAt;

    /**
     * 职业主键
     */
    private Integer jobId;

    /**
     * 文字类型
     */
    private Integer contentType;

    /**
     * 职业名称
     */
    private String careerName;
}

两种类型非常相似,只是座位数属性具有不同的名称,并且 type 属性在 Car 类中是特殊的枚举类型,但在 DTO 中是普通字符串。

4.2 mapper 接口

要生成用于从 Car 对象创建 CarDto 对象的映射器,需定义映射器接口:

package com.javagpt.back.converter;

import com.javagpt.back.entity.InterviewEntity;
import com.javagpt.back.vo.InterviewVO;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;

/**
 * @author JavaEdge
 * @date 2023/10/24
 */
// @Mapper注解将接口标记为映射接口,并让 MapStruct 处理器在编译时启动
@Mapper
public interface InterviewConverter {

   	// 可从 Mappers 类中检索接口实现的实例。按约定接口声明一个成员 INSTANCE,为客户端提供访问
    InterviewConverter INSTANCE = Mappers.getMapper(InterviewConverter.class);

  	// 对于src对象和target对象中名称不同的属性,可用@Mapping注解配置名称
    @Mapping(source = "numberOfSeats", target = "seatCount")
    // 实际的映射方法:期望源对象作为参数,并返回目标对象。方法名自由写
    InterviewVO to(InterviewEntity interviewEntity); 2
}

可能的情况下,将为src和taget中具有不同类型的属性执行类型转换,例如type属性将从枚举类型转换为字符串。

当然,一个接口中可以有多种映射方法,所有这些方法都将由 MapStruct 生成一个实现。

4.3 使用映射器

基于映射器接口,客户端可以以非常简单且类型安全的方式执行对象映射:

@Test
public void shouldMapCarToDto() {

    CarDto carDto = CarMapper.INSTANCE.carToCarDto( car );
}
举报

相关推荐

0 条评论