首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

MapStruct映射到不可修改的模型类

基础概念

MapStruct 是一个用于生成类型安全且易于使用的对象映射代码的框架。它通过注解处理器在编译时生成映射代码,从而避免了运行时的反射开销。不可修改的模型类通常指的是那些一旦创建后其状态就不能被改变的类,例如使用 final 关键字修饰的类或使用 Collections.unmodifiableList 等方法创建的集合。

相关优势

  1. 类型安全:MapStruct 在编译时生成映射代码,可以在编译阶段发现类型不匹配的问题。
  2. 性能:由于映射代码是在编译时生成的,运行时不需要反射,因此性能较高。
  3. 易于维护:生成的代码结构清晰,易于理解和维护。

类型

MapStruct 支持多种类型的映射,包括基本类型、集合、嵌套对象等。对于不可修改的模型类,MapStruct 可以生成相应的映射代码,确保目标对象也是不可修改的。

应用场景

在需要将一个对象的属性映射到另一个对象的场景中,尤其是当目标对象是不可修改的模型类时,MapStruct 非常有用。例如,在数据传输对象(DTO)和领域模型之间的转换,或者在微服务架构中不同服务之间的数据转换。

遇到的问题及解决方法

问题:为什么 MapStruct 映射到不可修改的模型类时会失败?

原因

  1. 不可修改性约束:如果目标对象是不可修改的,而映射过程中需要修改目标对象的属性,就会导致失败。
  2. 类型不匹配:源对象和目标对象的属性类型不匹配。

解决方法

  1. 确保目标对象的不可修改性:在映射过程中,确保目标对象的属性是不可修改的。可以使用 @Mapping(target = "property", ignore = true) 忽略某些属性,或者使用 @AfterMapping 注解在映射完成后进行必要的处理。
  2. 类型匹配:确保源对象和目标对象的属性类型匹配。如果类型不匹配,可以使用 @Mapping(source = "sourceProperty", target = "targetProperty") 进行显式映射。

示例代码

假设有两个类 SourceTarget,其中 Target 是不可修改的模型类:

代码语言:txt
复制
public class Source {
    private String name;
    private int age;
    // getters and setters
}

public final class Target {
    private final String name;
    private final int age;

    public Target(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // getters
}

使用 MapStruct 进行映射:

代码语言:txt
复制
@Mapper
public interface SourceTargetMapper {
    SourceTargetMapper INSTANCE = Mappers.getMapper(SourceTargetMapper.class);

    @Mapping(target = "name", source = "name")
    @Mapping(target = "age", source = "age")
    Target toTarget(Source source);
}

Target 类中添加一个静态工厂方法:

代码语言:txt
复制
public final class Target {
    private final String name;
    private final int age;

    private Target(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public static Target of(String name, int age) {
        return new Target(name, age);
    }

    // getters
}

修改映射器:

代码语言:txt
复制
@Mapper
public interface SourceTargetMapper {
    SourceTargetMapper INSTANCE = Mappers.getMapper(SourceTargetMapper.class);

    @Mapping(target = "name", source = "name")
    @Mapping(target = "age", source = "age")
    Target toTarget(Source source);

    default Target map(Source source) {
        return Target.of(source.getName(), source.getAge());
    }
}

参考链接

MapStruct 官方文档

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

MapStruct才是王者!【附源码】

多层应用程序通常需要在不同对象模型(例如实体和 DTO)之间进行映射。编写这样映射代码是一项乏味且容易出错任务。MapStruct 旨在通过尽可能自动化来简化这项工作。...target:属性目标名称,同一目标属性不能映射多次。如果用于映射枚举常量,则将给出常量成员名称,在这种情况下,源枚举中多个值可以映射到目标枚举相同值。...如果可能,MapStruct 将分配为文字;如果不可能,MapStruct 将尝试应用用户定义映射方法。...假设 B 复制了 A ,修改 A 时候,看 B 是否发生变化:如果 B 跟着也变了,说明是浅拷贝,拿人手短!(修改堆内存中同一个值);如果 B 没有改变,说明是深拷贝,自食其力!...(修改堆内存中不同值) MapStruct 中是创建新对象,也就是深拷贝。

2K20

你居然不知道MapStruct

MyBtatis从数据库中查询数据映射到domain实体上,然后有时候需要将domain实体映射给前端VO,用于展示。...例如Student我们将学生名字和年龄映射到VO中,但是不创建新实例。...另一个例子是对其他对象引用,这些对象应该映射到目标模型相应类型。例如:Teachr可能有一个Wife类型属性wife,在映射VO对象时需要将其转换为StudentVO对象。...输出结果如下所示 当然MapStruct也支持其他各种类型集合映射,上面只是举例了Map映射 9.映射枚举 MapStruct支持生成将一个Java枚举类型映射到另一个Java枚举类型方法。...默认情况下,源枚举中每个常量都映射到目标枚举类型中具有相同名称常量。如果需要,可以使用@ValueMapping注解将源枚举中常量映射到具有其他名称常量。

2.4K31
  • 5分钟聊一聊Java中原型模式

    本文将深入探讨原型模式深复制和浅复制,并介绍如何结合 MapStruct 工具进行对象转换。原型模式概述原型模式核心思想是通过复制现有对象来创建新对象,而不是通过构造函数逐步初始化对象。...复制后 Sheep 对象与原对象共享 birth 字段引用。如果我们修改原对象 birth 日期,新对象 birth 日期也会改变。...MapStruct 提供了一种高效方式来将一个对象属性映射到另一个对象,特别适合用于数据传输对象(DTO)和业务对象(BO)之间转换。...这样,我们能够高效地将对象数据传递到不同模型中,而不必手动编写繁琐转换代码。...浅复制和深复制是实现克隆两种主要方式,浅复制简单但可能导致共享引用问题,而深复制则更加全面但开销更大。结合 MapStruct 工具,可以进一步提高对象转换效率,简化数据传递和处理过程。

    13231

    帮助 Java 开发人员进行 Bean 映射 8 大框架

    尽管将一个对象映射到另一个对象是很常见,但由于这两个具有相似或相同映射属性,它通常可能是迭代且乏味。幸运是,有几个 Java 映射框架可以用来递归地将数据从一个对象复制到另一个对象。...,其中实例化模型是真实实例创建或抽象特定实现,例如对象。...JMapper 以零内存消耗提供动态转换、关系映射和静态代码性能优势。它接受两个输入,Destination(将创建或修改实例)和 Source(包含数据实例)。...要使用 MapStruct,您需要定义映射器接口,声明所有必需映射方法。...只有在该数据映射到其他对象之后。 重映射 ReMap 是一个 Java 映射库,可帮助开发人员逐个属性地简化对象转换,同时减少映射器单元测试。

    2.3K10

    MapStruct1.5使用教程(高级版)

    在多层架构应用中,经常需要在不同对象模型之间进行转换,例如在持久层实体和传输层DTO(Data Transfer Object,数据传输对象)之间。...使用MapStruct,开发者只需要定义一个接口,并在接口中声明源对象和目标对象之间映射关系,MapStruct会在编译时自动生成映射实现。...枚举映射 MapStruct @ValueMapping 注解是用来映射枚举值。这个注解只能在 @Mapper 接口或抽象中使用。...使用构造函数映射 从MapStruct 1.5开始,你可以使用构造函数来创建目标对象。你只需要在你目标中定义一个合适构造函数,MapStruct就会自动使用它。...通过这样配置 @MapMapping 注解,MapStruct 将自动生成适当映射代码,按照指定映射规则将源 Map 中键值对映射到目标 Map。

    1.5K10

    对象拷贝 - 优雅解决方案 Mapstruct

    会将同名属性拷贝到另外一个对象中,操作方便但是存在一个缺陷 (速度慢) 有些同名字段却无法进行特殊化处理,将会导致不想修改字段被覆盖。...我们不喜欢将所有字段都显示给前端,或者我们需要修改字段返回给前端,例如 数据中存储上架下架是0,1  但是前端需要字段是true 和 false。...我们都得进行手动判断处理然后编辑成DTO返回给前端 MapStruct是一种类型安全bean映射生成java注释处理器。 我们要做就是定义一个映射器接口,声明任何必需映射方法。...在这种情况下,MapStruct将生成抽象扩展,并实现所有抽象方法。...,MapStruct将查找将 Date 对象映射到String方法,在 DateMapper 该类上找到它并生成 asString() 用于映射该 manufacturingDate 属性调用 映射集合

    6.8K20

    干掉 BeanUtils!试试这款 Bean 自动映射工具,真心强大!!

    开发手册》分层领域模型规约,不能一个对象走天下,需要定义成 POJO/DO/BO/DTO/VO/Query 等数据对象,完整定义可以参考阿里开发手册,关注公众号:Java技术栈,在后台回复:手册,可以获取最新高清完整版...MapStruct 优势: 1、MapStruct 使用简单方法调用生成映射代码,因此***速度非常快***; 2、类型安全,避免出错,只能映射相互映射对象和属性,因此不会错误将用户实体错误地映射到订单...MapStruct 实战 本文栈长基于 IntelliJ IDEA、Spring Boot、Maven 进行演示。 基本准备 新增两个数据库 DO : 一个用户主,一个用户扩展。...用户展示,包含用户主、用户扩展部分数据。...来看编译后目录: 原理就是在编译期间生成了一个该接口实现

    76310

    NullException、Token作用、Mapstruct用法

    1.Java中空指针异常 空指针出现: 从空对象中获取 / 修改值,如从数据库获取数据赋值给对象,再从当前对象中取值。...访问或修改空对象字段 取Null长度(如数组) 将Null抛出 规避空指针出现: 在使用对象时,确保将其初始化 声名引用变量时,必须从对象请求方法或字段之前,做判空处理 参考文章:NullException...UserConfig { private String field1; private Integer field2; } } 同等解决方案:BeanUtils工具...copyProperty以及调用getter/setter方法进行属性赋值 MapStruct优点: 通过使用普通方法调用而不是反射来快速执行 编译时类型安全性:只能映射相互映射对象和属性,不能将订单实体意外映射到客户...MapStructGithub关于无法遵循isXXX命名规则 Issues

    1.4K42

    MapStruct:Java代码转换终极武器

    3.1 Mapper接口定义@Mapperpublic interface PersonMapper { PersonDto toDto(Person person);}3.2 实体定义public...应用场景MapStruct适用于任何需要对象映射场景,如数据传输对象(DTO)和数据库实体之间映射。5. 代码示例下面是一个使用MapStruct示例,展示了如何将实体射到数据传输对象。...注解处理器MapStruct使用了Java注解处理器API来生成映射代码。在编译时,注解处理器会读取源代码中@Mapper注解,并根据定义映射规则生成相应映射。...MapStruct会根据这些规则生成实际映射代码。源码解读为了更好地理解MapStruct工作原理,我们来简单解读一下MapStruct源码。...领域模型转换:在不同领域模型之间转换数据。服务层转换:在服务层之间转换数据。代码示例让我们通过一个详细代码示例来展示MapStruct实际应用。

    32910

    java开发中DTO、VO、PO之间转换你应该这么操作

    痛点 一种框架出现都要解决个痛点,我想下面这这种不方便操作经常有人写吧。 假如Car 是数据库映射 ? ? CarDTO是DTO ? 通常我们会这么写一个方法进行转换 ?...mapStruct 最终调用是setter和getter 方法,而非反射。这也是其性能比较好原因之一。numberOfSeats 映射到seatCount 就比较好理解了。...我们是不是忘记了一个属性make,因为他们位置且名称完全一致,所以可以省略。而且对于包装是自动拆箱封箱操作,并且是线程安全。...这是处理数字格式化操作,遵循java.text.DecimalFormat规范 @Mapping(source = "price", numberFormat = "$#.00") 下面展示了将一个日期集合映射到日期字符串集合格式化操作上...总结 其实MapStruct 还有很多功能。但是从可读性来说,我建议使用以上几种容易理解功能即可。如果你感兴趣可以去mapstruct.org进一步学习。

    8.9K20

    干掉 BeanUtils!试试这款 Bean 自动映射工具,真心强大!

    关于BeanUtils 平时我经常使用Hutool中BeanUtil来实现对象转换,用多了之后就发现有些缺点: 对象属性映射使用反射来实现,性能比较低; 对于不同名称或不同类型属性无法转换,还得单独写...使用时候我们只要在接口中定义好对象属性映射规则,它就能自动生成映射实现,不使用反射,性能优秀,能实现各种复杂映射。...实现原理很简单,就是根据我们在Mapper接口中使用@Mapper和@Mapping等注解,在运行时生成接口实现,我们可以打开项目的target目录看下; 下面是MapStruct为MemberMapper...合并映射 MapStruct也支持把多个对象属性映射到一个对象中去。...例如这里把Member和Order部分属性映射到MemberOrderDto中去; /** * 会员商品信息组合Dto * Created by macro on 2021/10/21. */

    1.9K20

    第三十章:SpringBoot使用MapStruct自动映射DTO

    MapStruct是一种类型安全bean映射生成java注释处理器。 我们要做就是定义一个映射器接口,声明任何必需映射方法。在编译过程中,MapStruct会生成此接口实现。...,对应查询出信息后,我们需要使用MapStruct自动映射到GoodInfoDTO。...@Mapper注解是用于标注接口、抽象是被MapStruct自动映射标识,只有存在该注解才会将内部接口方法自动实现。...target代表是映射到方法方法值内字段名称,配置如上面GoodInfoMapper所示。...总结 本章主要讲述了基于SpringBoot开发框架上集成MapStruct自动映射框架,完成模拟多表获取数据后将某一些字段通过@Mapping配置自动映射到DTO实体实例指定字段内。

    5.3K70

    丢弃掉那些 BeanUtils 工具吧,MapStruct 是真香!!!

    应用分层 分层之后,每一层都有自己领域模型,即不同类型 Bean: DO(Data Object):与数据库表结构一一对应,通过DAO层向上传输数据源对象。...如下是 MapStruct 简介,胖友可以简单了解下: “MapStruct 是用于生成类型安全 Bean 映射 Java 注解处理器。... 处,通过调用 Mappers #getMapper(Class clazz) 方法,获得 MapStruct 帮我们自动生成 UserConvert 实现对象。...删除 setter、getter 方法 } 3.3 UserBO 修改 UserBO ,使用 Lombok @Data 注解替代 setter、getter 方法。...省略 setter/getter 方法 } 4.2 UserConvert 修改 UserConvert ,增加 @Mapping 注解使用示例。

    2.2K50

    Java Review - MapStruct全掌握:8个案例探究高效快捷Java对象映射

    MapStruct工作原理 MapStruct基于JavaJSR 269规范,该规范允许在编译期处理注解。MapStruct通过定义注解处理器,在编译期读取映射接口,并生成相应实现。...编译代码:编译项目时,MapStruct注解处理器会根据定义映射规则生成实现。 使用映射器:在代码中,通过Mappers.getMapper()方法获取映射器实例,并调用映射方法。...易于理解,减少了编写和维护大量样板代码需要。 缺点: 必须定义接口或抽象,可能在一定程度上增加了代码复杂性。 对于复杂映射逻辑,可能需要编写自定义映射函数。...只需定义一个映射器接口,并使用注解指定源和目标MapStruct会在编译期生成实现。...通过定义一个映射器接口,可以实现多个子类对象映射到一个父对象。

    3.4K10

    MapStruct 才是王者!一文玩转 MapStruct 全场景【附源码】

    大家好,我是mbb 作为一名基于Spring摸爬滚打了数年码农;各种无脑苦力活,可以说至少占据了一半变成人生;比如说,对象拷贝,无脑get、set调用;但是基于MVC下,各种实体间转换,又是必不可...---- 来源于官网 性能 以下是Java各种拷贝方式耗时对比: MapStruct优点 相比于手动get、set 无需手写转换工具,减轻大量体力活 相比与其他动态映射 效率高 核心转换逻辑并不是通过反射实现...userDTO * @return */ UserVO userVO2UserDTO(UserDTO userDTO); } componentModel 属性用于指定自动生成接口实现组件类型...,这个属性支持四个值: default: 这是默认情况;通过ClassLoader加载 jsr330: 生成实现上会添加@javax.inject.Named 和@Singleton注解,可以通过...可以将target目录删除重新编译测试;防止因为修改为编译导致不生效情况。

    4.6K21

    Java对象拷贝_对象拷贝有几种方法

    MapstructMapStruct是一个Java 注释处理器,用于为Java Bean生成类型安全和高性能映射器。它使您不必手工编写映射代码,这是一个繁琐且容易出错任务。...与运行时工作映射框架相比,MapStruct具有以下优点: 通过使用普通方法调用而不是反射来快速执行 编译时类型安全。只能映射彼此映射对象和属性,因此不会将订单实体意外映射到客户DTO等。...) github mapstruct/mapstruct 4、BeanCopier:BeanCopier是Cglib包中一个,用于对象复制。...创建一个新对象,然后将当前对象非静态字段复制到该新对象,无论该字段是值类型还是引用类型,都复制独立一份。当你修改其中一个对象任何内容时,都不会影响另一个对象内容。...源和目标有相同属性(两者getter都存在),但是目标setter不存在,此时会抛出NullPointerException。

    4.9K10

    满屏get & set 太Low了?试试 MapStruct 高级玩法

    作为一名Spring工程师;各种无脑苦力活,可以说至少占据了一半编程人生;比如说,对象拷贝,无脑get、set调用;但是基于MVC下,各种实体间转换,又是必不可。...---- 来源于官网 性能 以下是Java各种拷贝方式耗时对比: MapStruct优点 相比于手动get、set 无需手写转换工具,减轻大量体力活 相比与其他动态映射 效率高 核心转换逻辑并不是通过反射实现...userDTO * @return */ UserVO userVO2UserDTO(UserDTO userDTO); } componentModel 属性用于指定自动生成接口实现组件类型...,这个属性支持四个值: default: 这是默认情况;通过ClassLoader加载 jsr330: 生成实现上会添加@javax.inject.Named 和@Singleton注解,可以通过...可以将target目录删除重新编译测试;防止因为修改为编译导致不生效情况。

    3.3K20
    领券