当前位置: 首页 > article >正文

MapStruct工具类的使用

文章目录

  • 1.简介
  • 2.作用
    • 2.1 属性拷贝
    • 2.2 类型安全
    • 2.3 性能高效
    • 2.4 自定义转换
  • 3.如何使用
    • 3.1 创建一个maven工程项目并引入mapstruct的坐标依赖:
    • 3.2 源对象类
    • 3.3 目标对象类(和源对象类中的字段属性名相同)
    • 3.4 创建接口SyncMapper(接口名自定义)
    • 3.5 执行
    • 3.6 改动目标对象类属性(和源对象类中的字段属性名不相同)

1.简介

MapStruct是一个代码生成器,它基于约定优于配置的原则,通过注解的方式,将Java bean对象之间进行属性拷贝。它避免了手动编写繁琐的getter/setter调用代码,大大提高了开发效率,并且生成的代码类型安全、性能高效。

2.作用

2.1 属性拷贝

MapStruct主要用于Java bean之间的属性拷贝。例如,您有一个用户信息的DTO(数据传输对象)和一个用户信息的实体类,这两个类之间有很多相同的属性。使用MapStruct,您可以定义一个Mapper接口,并通过注解指定源对象和目标对象,MapStruct会自动生成实现这个Mapper接口的代码,完成属性拷贝的工作。

2.2 类型安全

由于MapStruct是基于注解和代码生成的,它可以在编译时期就检查类型安全。如果源对象和目标对象的属性类型不匹配,编译将会失败,这有助于及早发现问题。

2.3 性能高效

MapStruct生成的代码是直接调用getter和setter方法,而不是使用反射,因此性能非常高效。这使得它非常适合在高并发、高性能要求的场景中使用。

2.4 自定义转换

MapStruct还支持自定义转换逻辑。如果您需要对某个属性的拷贝进行特殊处理,比如日期格式的转换,您可以通过实现自定义的转换方法,并在Mapper接口中指定使用这个方法进行转换。

3.如何使用

3.1 创建一个maven工程项目并引入mapstruct的坐标依赖:

<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct</artifactId>
    <version>1.5.2.Final</version> <!-- 请使用最新版本 -->
</dependency>
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-processor</artifactId>
    <version>1.5.2.Final</version> <!-- 请使用最新版本 -->
    <scope>provided</scope>
</dependency>

3.2 源对象类

/**
 * @ClassName JyFullOnlineTimeDO
 * @Description TODO
 * @Author xiaoxiao
 * @Date 2025/1/24
 */
public class JyFullOnlineTimeDO {

    private String reservedFieldOne;
    private String reservedFieldTwo;
    private String reservedFieldThree;

    // create getter and setter methods
    public String getReservedFieldOne() {
        return reservedFieldOne;
    }

    public void setReservedFieldOne(String reservedFieldOne) {
        this.reservedFieldOne = reservedFieldOne;
    }

    public String getReservedFieldTwo() {
        return reservedFieldTwo;
    }

    public void setReservedFieldTwo(String reservedFieldTwo) {
        this.reservedFieldTwo = reservedFieldTwo;
    }

    public String getReservedFieldThree() {
        return reservedFieldThree;
    }

    public void setReservedFieldThree(String reservedFieldThree) {
        this.reservedFieldThree = reservedFieldThree;
    }

}

3.3 目标对象类(和源对象类中的字段属性名相同)

/**
 * @ClassName CompanyOnlineSyncVO
 * @Description TODO
 * @Author xiaoxiao
 * @Date 2025/1/24
 */
public class CompanyOnlineSyncVO {

    private String reservedFieldOne;
    private String reservedFieldTwo;
    private String reservedFieldThree;
    //生成以上字段的getter和setter方法
    public String getReservedFieldOne() {
        return reservedFieldOne;
    }

    public void setReservedFieldOne(String reservedFieldOne) {
        this.reservedFieldOne = reservedFieldOne;
    }

    public String getReservedFieldTwo() {
        return reservedFieldTwo;
    }

    public void setReservedFieldTwo(String reservedFieldTwo) {
        this.reservedFieldTwo = reservedFieldTwo;
    }

    public String getReservedFieldThree() {
        return reservedFieldThree;
    }

    public void setReservedFieldThree(String reservedFieldThree) {
        this.reservedFieldThree = reservedFieldThree;
    }
}
@Override
public String toString() {
    return "CompanyOnlineSyncVO{" +
            "reservedFieldOne='" + reservedFieldOne + '\'' +
            ", reservedFieldTwo='" + reservedFieldTwo + '\'' +
            ", reservedFieldThree='" + reservedFieldThree + '\'' +
            '}';
}

3.4 创建接口SyncMapper(接口名自定义)

import org.mapstruct.Mapper;
import java.util.List;

/**
 * @ClassName SyncMapper
 * @Description TODO
 * @Author xiaoxiao
 * @Date 2025/1/24
 */
@Mapper
public interface SyncMapper {
    SyncMapper INSTANCE = Mappers.getMapper(SyncMapper.class);
    
    CompanyOnlineSyncVO toVO(JyFullOnlineTimeDO jyFullOnlineTimeDO);
	
	List<CompanyOnlineSyncVO> toVOList(List<JyFullOnlineTimeDO> doList);
}

SyncMapper 接口中定义了两个方法,其中一个方法将JyFullOnlineTimeDO对象转换为CompanyOnlineSyncVO对象,另一个方法是将JyFullOnlineTimeDO对象集合转换为CompanyOnlineSyncVO对象集合。

3.5 执行

对象间转换演示:

public class Main {
    public static void main(String[] args) {
        // 创建JyFullOnlineTimeDO对象列表
        JyFullOnlineTimeDO do1 = new JyFullOnlineTimeDO();
        do1.setReservedFieldOne("Value1");
        do1.setReservedFieldTwo("Value2");
        do1.setReservedFieldThree("Value3");

        final CompanyOnlineSyncVO aDo = SyncMapper.INSTANCE.toVO(do1);
        System.out.println("aDo: " + aDo.toString());
}

输出:aDo: CompanyOnlineSyncVO{reservedFieldOne=‘Value1’, reservedFieldTwo=‘Value2’, reservedFieldThree=‘Value3’}

在执行main的时,程序编译过程中会生成一个SyncMapper接口的实现类SyncMapperImpl(此类是在target下,故无需自己编辑)
在这里插入图片描述
集合间转换演示:

public class Main {
    public static void main(String[] args) {
        // 创建JyFullOnlineTimeDO对象列表
        JyFullOnlineTimeDO do1 = new JyFullOnlineTimeDO();
        do1.setReservedFieldOne("Value1-1");
        do1.setReservedFieldTwo("Value1-2");
        do1.setReservedFieldThree("Value1-3");

        JyFullOnlineTimeDO do2 = new JyFullOnlineTimeDO();
        do2.setReservedFieldOne("Value2-1");
        do2.setReservedFieldTwo("Value2-2");
        do2.setReservedFieldThree("Value2-3");

        List<JyFullOnlineTimeDO> doList = Arrays.asList(do1, do2);

        // 执行映射操作
        List<CompanyOnlineSyncVO> voList = SyncMapper.INSTANCE.toVOList(doList);

        // 输出结果
        for (CompanyOnlineSyncVO vo : voList) {
            System.out.println("vo: " + vo.toString());
        }
    }
}

输出:
vo: CompanyOnlineSyncVO{reservedFieldOne=‘Value1-1’, reservedFieldTwo=‘Value1-2’, reservedFieldThree=‘Value1-3’}
vo: CompanyOnlineSyncVO{reservedFieldOne=‘Value2-1’, reservedFieldTwo=‘Value2-2’, reservedFieldThree=‘Value2-3’}
在这里插入图片描述
toVOList方法在编译过程中自动生成的实现类中,在内部实现上利用了之前的toVO方法。

下面演示:目标对象类和源对象类中的字段属性名不相同时

3.6 改动目标对象类属性(和源对象类中的字段属性名不相同)

public class CompanyOnlineSyncVO {

    private String zbyzd1;
    private String zbyzd2;
    private String zbyzd3;

    //create getter 和 setter 方法
    public String getZbyzd1() {
        return zbyzd1;
    }

    public void setZbyzd1(String zbyzd1) {
        this.zbyzd1 = zbyzd1;
    }

    public String getZbyzd2() {
        return zbyzd2;
    }

    public void setZbyzd2(String zbyzd2) {
        this.zbyzd2 = zbyzd2;
    }

    public String getZbyzd3() {
        return zbyzd3;
    }

    public void setZbyzd3(String zbyzd3) {
        this.zbyzd3 = zbyzd3;
    }

    @Override
    public String toString() {
        return "CompanyOnlineSyncVO{" +
                "zbyzd1='" + zbyzd1 + '\'' +
                ", zbyzd2='" + zbyzd2 + '\'' +
                ", zbyzd3='" + zbyzd3 + '\'' +
                '}';
    }
}

此时想要实现转换,需要手动指定字段间的映射关系

@Mapper
public interface SyncMapper {

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

   //@Mapping(source = "reservedFieldTwo", target = "zbyzd2") //如何只有一个字段需要手动指定时使用
   //当需要多个字段需要手动指定映射关系时,需要使用@Mappings进行包裹
    @Mappings({
            @Mapping(source = "reservedFieldOne", target = "zbyzd1"),
            @Mapping(source = "reservedFieldTwo", target = "zbyzd2"),
            @Mapping(source = "reservedFieldThree", target = "zbyzd3")
    })
    CompanyOnlineSyncVO toVO(JyFullOnlineTimeDO jyFullOnlineTimeDO);
    //不要把字段的映射关系注解放到集合上的方法上,不会起作用,放到toVO方法就行,因为其内部实现也是调用toVO,首先保证存在自己定义的单个对象间的转换的toVO方法。
    /*@Mappings({
            @Mapping(source = "reservedFieldOne", target = "zbyzd1"),
            @Mapping(source = "reservedFieldTwo", target = "zbyzd2"),
            @Mapping(source = "reservedFieldThree", target = "zbyzd3")
    })*/
    List<CompanyOnlineSyncVO> toVOList(List<JyFullOnlineTimeDO> doList);//当需要转换的集合对象间的属性不一致时,手动写出单个对象间转换的toVO方法,并在toVO方法上使用@Mappings{.....}或@Mapping(...)是必要的,否则实现不了集合对象间的属性不一致时的,集合间的转换。
}

此时编译后,生成的SyncMapperImpl实现类内容如下:
在这里插入图片描述
在这里插入图片描述
从而实现了,不同字段名时的一一对应的拷贝;
Mapping注解里,还有其他的属性:如时间格式转换等;可将源对象中的Date类型字段 转为指定时间格式的字符串后拷贝给目标对象中的字符串类型的字段
在这里插入图片描述


http://www.kler.cn/a/533816.html

相关文章:

  • solidity高阶 -- 调用接口合约
  • 【C++】STL——vector底层实现
  • Leetcode922: 按奇偶排序数组 II
  • JavaScript系列(57)--工程化实践详解
  • 人类心智逆向工程:AGI的认知科学基础
  • modbus协议处理
  • [论文笔记] Deepseek技术报告
  • 【Elasticsearch】`auto_date_histogram`聚合功能详解
  • MLA 架构
  • Ubuntu部署Deepseek-R1模型(8b)
  • 基于微信小程序的医院综合服务平台的设计与实现ssm+论文源码调试
  • 亚博microros小车-原生ubuntu支持系列:22 物体识别追踪
  • AI绘画:解锁商业设计新宇宙(6/10)
  • 使用request库实现接口测试-笔记
  • 阿里云 ubuntu22.04 中国区节点安装 Docker
  • 2024年12月 Scratch 图形化(一级)真题解析 中国电子学会全国青少年软件编程等级考试
  • arm 下 多线程访问同一变量 ,使用原子操作 性能差问题
  • 【Git】二、分支管理详解
  • 2024年12月 Scratch 图形化(三级)真题解析 中国电子学会全国青少年软件编程等级考试
  • 记录一下 在Mac下用pyinstallter 打包 Django项目
  • 自己实现的一个缓存数据库(搞着玩) .net Core/6/8/9
  • 【C语言高级特性】位操作(二):应用场景
  • python开发:爬虫示例——GET和POST请求处理
  • vue2-给data动态添加属性
  • WPS中解除工作表密码保护(忘记密码)
  • 手写MVVM框架-实现v-model(单向绑定)