java - MapStruct

链接

MapStruct GitHub

MapStruct

常用开发库 - MapStruct工具库详解

简介

首先要编写一个接口, 然后在接口中定义方法, 再在方法上放一些注解, 就可以让 MapStruct 生成一个实现类, 就可以用了.

由于是编译时生成了一个实现类, 所以很快.

  • [ 优点 ] 执行快; 自动处理一些东西 ( 字段同名自动映射, 简单类型自动转换 )
  • [ 缺点 ] 没找着中文文档;
  • [ 场景 ] 一或多个对象生成一个新对象; 将字段拷贝到已有对象中; 深拷贝

依赖

  • 与 Lombok 一起用时, 应保证 Lombok 在 MapStruct 之前引入
<properties>
    <mapstruct.version>1.5.5.Final</mapstruct.version>
</properties>

<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct</artifactId>
    <version>${mapstruct.version}</version>
</dependency>
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-processor</artifactId>
    <version>${mapstruct.version}</version>
</dependency>

@Mapping 中的一些字段

  • target, [ str ] 指定 返回值 中的字段, 可以用 . 代指自己

赋值方式

  • constant, [ str ] 用常量赋值
  • source, [ str ] 用参数中的字段赋值, 多个参数时可以 参数名.字段
  • expression, [ str ] 用表达式赋值, 一般需要套一个 Java()

不常用的东西

  • dateFormat, [ str ] 日期格式化字符串, 在此贴上常用值 yyyy-MM-dd HH:mm:ss
  • numberFormat, [ str ] 数字格式化字符串, 比如限制两位小数 #.##, 更多去看 这一节
  • ignore, [ bool ] 是否忽略此字段

注入方式

// 方式一, 用工厂创建一个实例对象
MyMapping INSTANCE = Mappers.getMapper(MyMapping.class);

// 方式二, 开启控制反转配置 ( 也就是 @Autowired )
@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)

示例

自定义接口

import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;

// 注入方式二, 适配 spring 的控制反转
@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
public interface MyMapping {

    // 注入方式一, 用工厂创建一个实例对象
    MyMapping INSTANCE = Mappers.getMapper(MyMapping.class);

    // 一般不用写 @Mapping, 字段同名则自动映射
    Target convert(Source s);

}

在代码中使用刚刚定义的接口

public class Test {

    public static void main(String[] args) {
        Target t = MyMapping.INSTANCE.convert(new Source("a"));
        System.out.println(t); // Target(val=a)
    }

}

MapStruct 生成的接口的实现类

import javax.annotation.Generated;

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2024-01-30T16:37:59+0800",
    comments = "version: 1.5.5.Final, compiler: javac, environment: Java 11.0.20.1 (Amazon.com Inc.)"
)
public class MyMappingImpl implements MyMapping {

    @Override
    public Target convert(Source s) {
        if ( s == null ) {
            return null;
        }

        Target target = new Target();

        target.setVal( s.getVal() );

        return target;
    }
}

比较奇妙的用法

// 映射到一个已存在的对象上 ( 字段原值会被覆盖 )
// 用 @MappingTarget 指定 target
void convert(Source s, @MappingTarget Target t);

// 深拷贝 ( @Mapping 也支持该方式 )
@Mapper(mappingControl = DeepClone.class)

// 子类型映射 ( 方法返回的是父类型, 使用 @SubclassMapping 指定返回具体哪一个子类型 )
@SubclassMapping( source = AppleDto.class, target = Apple.class )

同层级映射

  • 比如, 在 source 向 target 映射时, 想将 source 中的字段 aDTO 转换成 target 中的字段 aVO, 可以单独定义一个 aDTO 到 aVO 的映射, 然后 MapStruct 就会自动识别并使用这个映射
// 不同字段映射
@Mapping(source = "x", target = "y")

// 多参数, 不同字段映射
@Mapping(target = "bId", source = "b.id")
@Mapping(target = "cName", source = "c.name")
A convert(B b, C c);

// 字符串转列表
@Mapping(target = "idList", expression="java(source.getIds().split(\",\"))")

跨层映射

// 将 source 的一个 field 映射到整个 target
@Mapping( target=".", source="source.field" )

// 将整个 source 映射到 target 的一个 field
@Mapping( target="field", source="source" )
  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值