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

性能高、上手快,实体类转换工具 MapStruct 到底有多强大

yuyutoo 2024-10-29 17:28 1 浏览 0 评论

1.什么是MapStruct

1.1 JavaBean 的困扰

对于代码中 JavaBean之间的转换, 一直是困扰我很久的事情。在开发的时候我看到业务代码之间有很多的 JavaBean 之间的相互转化, 非常的影响观感,却又不得不存在。我后来想的一个办法就是通过反射,或者自己写很多的转换器。

第一种通过反射的方法确实比较方便,但是现在无论是 BeanUtils, BeanCopier 等在使用反射的时候都会影响到性能。虽然我们可以进行反射信息的缓存来提高性能。但是像这种的话,需要类型和名称都一样才会进行映射,有很多时候,由于不同的团队之间使用的名词不一样,还是需要很多的手动 set/get 等功能。

第二种的话就是会很浪费时间,而且在添加新的字段的时候也要进行方法的修改。不过,由于不需要进行反射,其性能是很高的。推荐:Java进阶视频资源

1.2 MapStruct 带来的改变

MapSturct 是一个生成类型安全,高性能且无依赖的 JavaBean 映射代码的注解处理器(annotation processor)。

  • 注解处理器
  • 可以生成 JavaBean 之间那的映射代码
  • 类型安全,高性能,无依赖性

2.MapStruct 入门

2.1 添加依赖

2.2 po类

2.3 dto类

2.4 创建转换接口

2.5 测试方法

2.6 运行效果

2.7 查看编译的class

底层通过自动取值赋值操作完成

3.MapStruct优点分析

3.1 性能高

这是相对反射来说的,反射需要去读取字节码的内容,花销会比较大。而通过 MapStruct 来生成的代码,其类似于人手写。速度上可以得到保证。

3.2 使用简单

如果是完全映射的,使用起来肯定没有反射简单。用类似 BeanUtils 这些工具一条语句就搞定了。但是,如果需要进行特殊的匹配(特殊类型转换,多对一转换等),其相对来说也是比较简单的。

基本上,使用的时候,我们只需要声明一个接口,接口下写对应的方法,就可以使用了。当然,如果有特殊情况,是需要额外处理的。推荐:Java进阶视频资源

3.3 代码独立

生成的代码是对立的,没有运行时的依赖。

3.4 易于 debug

在我们生成的代码中,我们可以轻易的进行 debug。

4.MapStruct使用案例

4.1 属性名称相同

在实现类的时候,如果属性名称相同,则会进行对应的转化。通过此种方式,我们可以快速的编写出转换的方法。(入门案例)

4.2 属性名不相同

属性名不相同,在需要进行互相转化的时候,则我们可以通过@Mapping 注解来进行转化。

  • source 需要转换的对接,通常是入参
  • target 转换的对接,通常是出参
  • ignore 忽略,默认false不忽略,需要忽略设置为true
  • defaultValue 默认值
  • expressions 可以通过表达式来构造一些简单的转化关系。虽然设计的时候想兼容很多语言,不过目前只能写Java代码。
@Mappings({
            @Mapping(source = "birthdate", target = "birth"),//属性名不一致映射
            @Mapping(target = "birthformat", expression = "java(org.apache.commons.lang3.time.DateFormatUtils.format(person.getBirthdate(),\"yyyy-MM-dd HH:mm:ss\"))"),//自定义属性通过java代码映射
    })
public PersonVo PersonToPersonVo(Person person);

这里用到演示了如何使用TimeAndFormat对time和format操作,这里必须要指定需要使用的Java类的完整包名,不然编译的时候不知道你使用哪个Java类,会报错。

4.3 转换非基础类型属性

如果subUser与subUserDto字段名称相同直接配置即可完成(对象类型,包括list)

4.4 Mapper 中使用自定义的转换

有时候,对于某些类型,无法通过代码生成器的形式来进行处理。那么, 就需要自定义的方法来进行转换。这时候,我们可以在接口(同一个接口,后续还有调用别的 Mapper 的方法)中定义默认方法(Java8及之后)。

只能存在一个default修饰的方法

4.5 多转一

我们在实际的业务中少不了将多个对象转换成一个的场景。MapStruct 当然也支持多转一的操作。推荐:Java进阶视频资源

4.5.1 遵循原则

  • 当多个对象中, 有其中一个为 null, 则会直接返回 null
  • 如一对一转换一样, 属性通过名字来自动匹配。因此, 名称和类型相同的不需要进行特殊处理
  • 当多个原对象中,有相同名字的属性时,需要通过 @Mapping 注解来具体的指定, 以免出现歧义(不指定会报错)。如上面的 name

属性也可以直接从传入的参数来赋值

4.6 更新 Bean 对象

有时候,我们不是想返回一个新的 Bean 对象,而是希望更新传入对象的一些属性。这个在实际的时候也会经常使用到。

4.7 map映射

4.8 多级嵌套

只需要在mapper接口中定义相关的类型转换方法即可,list类型也适用

4.8.1 方式1

4.8.2 方式2

通过uses配置类型转换

5.获取 mapper

5.1 通过 Mapper 工厂获取

我们都是通过 Mappers.getMapper(xxx.class) 的方式来进行对应 Mapper 的获取。此种方法为通过 Mapper 工厂获取。

如果是此种方法,约定俗成的是在接口内定义一个接口本身的实例 INSTANCE, 以方便获取对应的实例。

这样在调用的时候,我们就不需要在重复的去实例化对象了。类似下面

Target target = SourceMapper.INSTANCE.source2target(source);

5.2 使用依赖注入

对于 Web 开发,依赖注入应该很熟悉。MapSturct 也支持使用依赖注入,同时也推荐使用依赖注入。

@Mapper(componentModel = "spring")

5.3 依赖注入策略

可以选择是通过构造方法或者属性注入,默认是属性注入。

类似如此使用

@Mapper(componentModel = "cdi" injectionStrategy = InjectionStrategy.CONSTRUCTOR)

5.4 自定义类型转换

有时候,在对象转换的时候可能会出现这样一个问题,就是源对象中的类型是Boolean类型,而目标对象类型是String类型,这种情况可以通过@Mapper的uses属性来实现:

要注意的是,如果使用了例如像spring这样的环境,Mapper引入uses类实例的方式将是自动注入,那么这个类也应该纳入Spring容器

相关推荐

MySQL5.5+配置主从同步并结合ThinkPHP5设置分布式数据库

前言:本文章是在同处局域网内的两台windows电脑,且MySQL是5.5以上版本下进行的一主多从同步配置,并且使用的是集成环境工具PHPStudy为例。最后就是ThinkPHP5的分布式的连接,读写...

thinkphp5多语言怎么切换(thinkphp5.1视频教程)

thinkphp5多语言进行切换的步骤:第一步,在配置文件中开启多语言配置。第二步,创建多语言目录。相关推荐:《ThinkPHP教程》第三步,编写语言包。视图代码:控制器代码:效果如下:以上就是thi...

基于 ThinkPHP5 + Bootstrap 的后台开发框架 FastAdmin

FastAdmin是一款基于ThinkPHP5+Bootstrap的极速后台开发框架。主要特性基于Auth验证的权限管理系统支持无限级父子级权限继承,父级的管理员可任意增删改子级管理员及权限设置支持单...

Thinkphp5.0 框架实现控制器向视图view赋值及视图view取值操作示

本文实例讲述了Thinkphp5.0框架实现控制器向视图view赋值及视图view取值操作。分享给大家供大家参考,具体如下:Thinkphp5.0控制器向视图view的赋值方式一(使用fetch()方...

thinkphp5实现简单评论回复功能(php评论回复功能源码下载)

由于之前写评论回复都是使用第三方插件:畅言所以也就没什么动手,现在证号在开发一个小的项目,所以就自己动手写评论回复,没写过还真不知道评论回复功能听着简单,但仔细研究起来却无法自拔,由于用户量少,所以...

ThinkPHP框架——实现定时任务,定时更新、清理数据

大家好,我是小蜗牛,今天给大家分享一下,如何用ThinkPHP5.1.*版本实现定时任务,例如凌晨12点更新数据、每隔10秒检测过期会员、每隔几分钟发送请求保证ip的活性等本次分享,主要用到一个名为E...

BeyongCms系统基于ThinkPHP5.1框架的轻量级内容管理系统

BeyongCms内容管理系统(简称BeyongCms)BeyongCms系统基于ThinkPHP5.1框架的轻量级内容管理系统,适用于企业Cms,个人站长等,针对移动App、小程序优化;提供完善简...

YimaoAdminv3企业建站系统,使用 thinkphp5.1.27 + mysql 开发

介绍YimaoAdminv3.0.0企业建站系统,使用thinkphp5.1.27+mysql开发。php要求5.6以上版本,推荐使用5.6,7.0,7.1,扩展(curl,...

ThinkAdmin-V5开发笔记(thinkpad做开发)

前言为了快速开发一款小程序管理后台,在众多的php开源后台中,最终选择了基于thinkphp5的,轻量级的thinkadmin系统,进行二次开发。该系统支持php7。文档地址ThinkAdmin-V5...

thinkphp5.0.9预处理导致的sql注入复现与详细分析

复现先搭建thinkphp5.0.9环境...

thinkphp5出现500错误怎么办(thinkphp页面错误)

thinkphp5出现500错误,如下图所示:相关推荐:《ThinkPHP教程》require():open_basedirrestrictionineffect.File(/home/ww...

Thinkphp5.0极速搭建restful风格接口层

下面是基于ThinkPHPV5.0RC4框架,以restful风格完成的新闻查询(get)、新闻增加(post)、新闻修改(put)、新闻删除(delete)等server接口层。1、下载Thin...

基于ThinkPHP5.1.34 LTS开发的快速开发框架DolphinPHP

DophinPHP(海豚PHP)是一个基于ThinkPHP5.1.34LTS开发的一套开源PHP快速开发框架,DophinPHP秉承极简、极速、极致的开发理念,为开发集成了基于数据-角色的权限管理机...

ThinkPHP5.*远程代码执行高危漏洞手工与升级修复解决方法

漏洞描述由于ThinkPHP5框架对控制器名没有进行足够的安全检测,导致在没有开启强制路由的情况下,黑客构造特定的请求,可直接GetWebShell。漏洞评级严重影响版本ThinkPHP5.0系列...

Thinkphp5代码执行学习(thinkphp 教程)

Thinkphp5代码执行学习缓存类RCE版本5.0.0<=ThinkPHP5<=5.0.10Tp框架搭建环境搭建测试payload...

取消回复欢迎 发表评论: