百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

Java 实体映射工具 MapStruct(jpa实体类映射类)

lipiwang 2025-06-09 23:26 10 浏览 0 评论

简介: 让你的DO(业务实体对象),DTO(数据传输对象)数据转换更简单强大

前言

在软件架构中,分层式结构是最常见,各层之间有其独立且隔离的业务逻辑,也因而各层有自己的输入输出对象,也就是代码中见到各种O,如DO、DTO、VO,这些数据对象之间通常都有很多相同或相近的属性对象,数据在传输的过程中从一个O到另一个O,就通常需要赋值,从最初的的get/set


Bash
personDTO.setName(personDO.getName());
personDTO.setAge(personDO.getAge());
personDTO.setSex(personDO.getSex());
personDTO.setBirthday(personDO.getBirthday());

到后来的BeanUtils(减少了set的代码量)

再到现在的MapStruct


1.MapStruct配置

MapStuct的使用非常简单,把对应的jar包引入即可。

Bash
<properties>
    <lombok-mapstruct-binding.version>0.2.0</lombok-mapstruct-binding.version>
    <org.mapstruct.version>1.3.0.Final</org.mapstruct.version>
    <org.mapstruct.processor.version>1.3.0.Final</org.mapstruct.processor.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct-jdk8</artifactId>
        <version>${org.mapstruct.version}</version>
    </dependency>
    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct-processor</artifactId>
        <version>${org.mapstruct.processor.version}</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

<configuration>
    <source>${java.version}</source>
    <target>${java.version}</target>
    <annotationProcessorPaths>
        <path>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct-processor</artifactId>
            <version>${org.mapstruct.processor.version}</version>
        </path>
        <path>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
        </path>
        <path>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok-mapstruct-binding</artifactId>
            <version>${lombok-mapstruct-binding.version}</version>
        </path>
    </annotationProcessorPaths>
</configuration>


2.原理

MapStruct属于在编译期,生成调用get/set方法进行赋值的代码,生成对应的java文件。在编译期间消耗少许的时间,换取运行时的高性能。


3.使用方法

先定义一个接口,按照规范我们在service或domainService下建一个converter包


通过依赖注入的方式获取Mapper实例

@Mapper(componentModel = "spring")




3.1 对于同名同属性的字段,无需特别声明指定,自动转换。

MapStructReq1

@Data
@Accessors(chain = true)
public class MapStructReq1 {

    private Integer id;
    private String name;
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date updateTime;

}

MapStructResp1:

@Data
@Accessors(chain = true)
public class MapStructResp1 {

    private Integer id;
    private String name;
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date updateTime;

}


converter:



serviceImpl:



controller:

调用demo1接口后,可以看到我们给MapStructReq1赋值后,成功拷贝到了MapStructResp1中返回

3.2 对于不同名相同属性的字段,可以使用Mapping注解指定。

MapStructReq1

@Data
@Accessors(chain = true)
public class MapStructReq1 {

    private Integer id;
    private String name;
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date updateTime;

}

MapStructResp2

@Data
public class MapStructResp2 {

    private Integer id;
    private String productName;
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date updateTime;

}

converter

@Mapping(source = "name", target = "productName")
MapStructResp2 req1ToResp2(MapStructReq1 req);


controller:

req1中的name字段拷贝到了resp2中的productName中



3.3 支持把多个参数映射成一个类型,使用@Mapping指定即可。

converter:

    @Mapping(source = "req1.id", target = "id")
    @Mapping(source = "req2.productName", target = "name")
    @Mapping(source = "req1.updateTime", target = "updateTime")
    MapStructResp1 req1And2ToResp1(MapStructReq1 req1, MapStructReq2 req2);

controller:

将req1中的id,req2中的name拷贝到了resp1中


3.4 对于基础数据类型会进行自动隐式的转换

如int、long、String,Integer、Long等。

req3

@Data
@Accessors(chain = true)
public class MapStructReq3 {

    private String id;
    private int name;
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date updateTime;

}

resp1:

@Data
@Accessors(chain = true)
public class MapStructResp1 {

    private Integer id;
    private String name;
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date updateTime;

}

converter:

controller:



String 类型的id转为了int型,int型的name转为了String型


3.5 集合的拷贝

req5

@Data
@Accessors(chain = true)
public class MapStructReq5 {

    private Integer id;
    private MapStructReq1 target;
    private List<MapStructReq1> list;

}

resp5

@Data
@Accessors(chain = true)
public class MapStructResp5 {

    private Integer id;
    private MapStructResp1 target;
    private List<MapStructResp1> list;

}

converter:

List<MapStructResp1> req1ListToResp1List(List<MapStructReq1> req1List);

controller:


3.6 嵌套对象的拷贝


converter:

MapStructResp5 req5ToResp5(MapStructReq5 req);


controller:

给target赋值为req1,给list赋值为4个不同名字的req1

3.7 使用java表达式进行映射

对于复杂的映射,允许使用java表达式实现字段的映射。

注意要导入使用到的类。


req6

@Data
@Accessors(chain = true)
public class MapStructReq6 {

    private Integer id;
    private int price1;
    private int price2;

}

resp6

@Data
@Accessors(chain = true)
public class MapStructResp6 {

    private Integer id;
    private int price1;
    private int price2;

}

DemoUtils

public class DemoUtils {

    public static int add(int val1, int val2) {
        return val1 + val2;
    }
}

converter:

@Mapper(componentModel = "spring", imports = {DemoUtils.class})//导入java表达式使用的类,导入多个类在{}中用逗号分隔
public interface MapStructConverterDemo1 {

    /**
     * 使用java表达式进行映射
     * @param req
     * @return
     */
    @Mapping(target = "price1", expression = "java(req.getPrice1() + req.getPrice2())")//直接相加
    @Mapping(target = "price2", expression = "java(DemoUtils.add(req.getPrice1(), req.getPrice2()))")//使用工具类处理
    MapStructResp6 req6ToResp6(MapStructReq6 req);
}

controller:

参考链接

https://www.cnblogs.com/gotten/p/13052911.html

相关推荐

ubuntu单机安装open-falcon极度详细操作

备注:以下操作均由本人实际操作并得到验证,喜欢的同学可尝试操作安装。步骤一1.1环境准备(使用系统:ubuntu18.04)1.1.1安装redisubuntu下安装(参考借鉴:https://...

Linux搭建promtail、loki、grafana轻量日志监控系统

一:简介日志监控告警系统,较为主流的是ELK(Elasticsearch、Logstash和Kibana核心套件构成),虽然优点是功能丰富,允许复杂的操作。但是,这些方案往往规模复杂,资源占用高,...

一文搞懂,WAF阻止恶意攻击的8种方法

WAF(Web应用程序防火墙)是应用程序和互联网流量之间的第一道防线,它监视和过滤Internet流量以阻止不良流量和恶意请求,WAF是确保Web服务的可用性和完整性的重要安全解决方案。它...

14配置appvolume(ios14.6配置文件)

使用AppVolumes应用程序功能,您可以管理应用程序的整个生命周期,包括打包、更新和停用应用程序。您还可以自定义应用程序分配,以向最终用户提供应用程序的特定版本14.1安装appvolume...

目前流行的缺陷管理工具(缺陷管理方式存在的优缺点)

摘自:https://blog.csdn.net/jasonteststudy/article/details/7090127?utm_medium=distribute.pc_relevant.no...

开源数字货币交易所开发学习笔记(2)——SpringCloud

前言码云(Gitee)上开源数字货币交易所源码CoinExchange的整体架构用了SpringCloud,对于经验丰富的Java程序员来说,可能很简单,但是对于我这种入门级程序员,还是有学习的必要的...

开发JAX-RPC Web Services for WebSphere(下)

在开发JAX-RPCWebServicesforWebSphere(上)一文中,小编为大家介绍了如何创建一个Web服务项目、如何创建一个服务类和Web服务,以及部署项目等内容。接下来小编将为大...

CXF学习笔记1(cxf client)

webservice是发布服务的简单并实用的一种技术了,个人学习了CXF这个框架,也比较简单,发布了一些笔记,希望对笔友收藏并有些作用哦1.什么是webServicewebService让一个程序可...

分布式RPC最全详解(图文全面总结)

分布式通信RPC是非常重要的分布式系统组件,大厂经常考察的Dubbo等RPC框架,下面我就全面来详解分布式通信RPC@mikechen本篇已收于mikechen原创超30万字《阿里架构师进阶专题合集》...

Oracle WebLogic远程命令执行0day漏洞(CVE-2019-2725补丁绕过)预警

概述近日,奇安信天眼与安服团队通过数据监控发现,野外出现OracleWebLogic远程命令执行漏洞最新利用代码,此攻击利用绕过了厂商今年4月底所发布的最新安全补丁(CVE-2019-2725)。由...

Spring IoC Container 原理解析(spring中ioc三种实现原理)

IoC、DI基础概念关于IoC和DI大家都不陌生,我们直接上martinfowler的原文,里面已经有DI的例子和spring的使用示例《InversionofControlContainer...

Arthas线上服务器问题排查(arthas部署)

1Arthas(阿尔萨斯)能为你做什么?这个类从哪个jar包加载的?为什么会报各种类相关的Exception?我改的代码为什么没有执行到?难道是我没commit?分支搞错了?遇到问题无法在...

工具篇之IDEA功能插件HTTP_CLENT(idea2021插件)

工具描述:Java开发人员通用的开发者工具IDEA集成了HTTPClient功能,之后可以无需单独安装使用PostMan用来模拟http请求。创建方式:1)简易模式Tools->HTTPCl...

RPC、Web Service等几种远程监控通信方式对比

几种远程监控通信方式的介绍一.RPCRPC使用C/S方式,采用http协议,发送请求到服务器,等待服务器返回结果。这个请求包括一个参数集和一个文本集,通常形成“classname.meth...

《github精选系列》——SpringBoot 全家桶

1简单总结1SpringBoot全家桶简介2项目简介3子项目列表4环境5运行6后续计划7问题反馈gitee地址:https://gitee.com/yidao620/springbo...

取消回复欢迎 发表评论: