Mapstruct

传送门

SpringMVC的源码解析(精品)
Spring6的源码解析(精品)
SpringBoot3框架(精品)
MyBatis框架(精品)
MyBatis-Plus
SpringDataJPA
SpringCloudNetflix
SpringCloudAlibaba(精品)
Shiro
SpringSecurity
java的LOG日志框架
Activiti(敬请期待)
JDK8新特性
JDK9新特性
JDK10新特性
JDK11新特性
JDK12新特性
JDK13新特性
JDK14新特性
JDK15新特性
JDK16新特性
JDK17新特性
JDK18新特性
JDK19新特性
JDK20新特性
JDK21新特性
其他技术文章传送门入口

一、概念

是一个类似于 BeanUtils.copyProperties(source,target);属性拷贝工具,将source对象的所有属性值对应的拷贝到target对象上。由于 BeanUtils.copyProperties(source,target)只拷贝属性名称相同的属性值,属性名称不同的不会拷贝,而MapStruct则更加强大和灵活,并且性能更好。

二、注解

注解作用
@Mapperorg.mapstruct包下,指明当前接口用于Mapstruct,用于属性拷贝
@Mappings默认属性相同的都会拷贝,当属性名称不同的时候,使用这个注解结合@Mapping,来让不同属性名称映射。
@Condition条件注解,除了作用到整个bean外还可以修饰具体的属性值,实现bean属性维度的条件转换。(就是拷贝的时候,要先判断这个注解标注的方法,符合这个方法,才会进行拷贝)
@InheritInverseConfiguration逆向映射
@Named自定义方法,配合qualifiedByName一起使用
@MappingTarget一个对象的信息更新到另一个对象上,指明另一个对象是谁

三、使用步骤

第一步:

创建一个接口,以所在业务的对应Controller命名,比如案例的Controller为PersonAdminController,这个接口就叫PersonAdminMapper,并且在vo.personAdminController包下面,一个业务Controller对应一个Mapper。并在接口上加上@Mapper ,注意Mapstruct的注解都是在org.mapstruct

package com.ours.www.demo.controller.vo.personAdminController;
@Mapper(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
public interface PersonAdminoMapper {

}  

第二步:

只需要接口中写业务需要的接口方法即可(这步就已经完成了)。

package com.ours.www.demo.controller.vo;

import com.ours.www.core.common.enums.GenderEnum;
import com.ours.www.core.framework.mvc.vo.PagerResponse;
import com.ours.www.demo.entity.PersonEntity;
import org.mapstruct.*;
import org.mapstruct.factory.Mappers;
import java.util.List;

@Mapper(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
// 不加的话,会将null拷贝给目前对象。 加上后,例如
// 现在 source对象 age=15 name=null   tagert对象  age=99 name=zt ;拷贝后  tagert对象 age=15 name=zt 。 不会将name值变为null
public interface PersonAdminMapper {

    // 固定写法,Controller或者Service层调用的时候使用INSTANCE变量。
    PersonAdminMapper INSTANCE = Mappers.getMapper(DemoMapper.class);

    // 请求参数变Entity
    PersonEntity rquestToEntity(CreatePersonRequest source);

    // Entity变返回结果
    @Mappings({
        @Mapping(source = "id", target = "_id"),// 默认相同属性名称都会拷贝,相同属性名称可以省略,不同属性名称必须@Mapping映射对应
    	@Mapping(target="auth2",ignore = true),// 忽略这个属性,不想拷贝的时候这样用。
    })
    CreatePersonResponse entityToCreateResponse(PersonEntity source);
}  

第三步:

开发不需要写接口实现类,在Build的时候idea会自动生成实现类,build以后可以在target目录中看到生成的实现类。
在这里插入图片描述

第四步:

使用。如下面代码中第19行,需要将PersonEntity实例的属性值拷贝到最后返回结果CreatePersonResponse上面,只需要在PersonAdminMapper接口写一个接口方法即可。
该接口方法如下:
CreatePersonResponse entityToCreateResponse(PersonEntity source);// 将source对象拷贝到返回结果对象上。

@Tag(name = "人员管理端接口")// @Tag 用来设置 Controller 的名称和描述
@AdminRestController("/demo/user")
@CheckLicense(LicenseModuleEnum.ehr_personManager)
public class PersonAdminController {

    private final PersonAdminService personAdminService;

    public PersonAdminController(PersonAdminService personAdminService) {
        this.personAdminService = personAdminService;
    }

    @Operation(summary = "添加人员")
    @PostMapping("/create")
    @CheckLicense(subs = SubLicenseEnum.level)
    @OursRBAC({OrgTypeEnum.hrPersonMgr, OrgTypeEnum.hrPersonMgr4Main})
    public R<CreatePersonResponse> createPerson(@Valid @RequestBody CreatePersonRequest createPersonRequest) {
        PersonEntity entity = personAdminService.createPerson(createPersonRequest);
        // 将source对象拷贝到返回结果CreatePersonResponse对象上
        CreatePersonResponse createPersonResponse = PersonAdminMapper.INSTANCE.entityToCreateResponse(entity);
        return R.ok(createPersonResponse);
    }
}

第五步:

需要 idea中下载 mapstruct support 插件,安装重启Idea,这样方便书写Mapstruct的get代码。

更多Mapstruct高级用法参考下面文章,实际代码见下面的增删改查示例代码:

Mapstruct的CSDN参考文章:https://blog.csdn.net/qq_44732146/article/details/119968376

四、Mapstruct的枚举使用

/**
 * 查询单个人员
*/
// Entity变返回结果
@Mappings({
// 语法说明:expression表示java表达式,java小括号里面内容就是一个方法,findEnumByValue是方法名,后面是该方法的两个参数。由于包权限问题,方法名和参数等根据情况需要写全类名。
// @Mapping(target="genderEnum",expression = "java(findEnumByValue(GenderEnum.class,source.getGender()))")// 相同包下可以省略全类名,但是由于GenderEnum、source、XxxMapper不在同一个包下,所以需要改成下行代码
// @Mapping(target="genderEnum",expression = "java(com.ours.www.core.common.enums.OursBaseEnum.findEnumByValue(com.ours.www.core.common.enums.GenderEnum.class,source.getGender()))")// 不同包需要全类名

// GenderEnum性别枚举举例: gender_male(1,"男"),
@Mapping(source = "gender", target = "gender"),// 枚举映射 普通属性值-》转化为枚举值 例如: 1-》1 备注:相同的可以省略不写,本行代码可以省略
@Mapping(target="genderDesc",expression = "java("+ findEnumDesByValue +"("+ genderEnum +",source.getGender()))"),// 枚举映射 普通属性值-》转化为枚举描述 例如: 1-》男
@Mapping(target="genderEnum",expression = "java("+ findEnumByValue +"("+ genderEnum +",source.getGender()))"),// 枚举映射 普通属性值-》转化为枚举对象 例如: 1-》GenderEnum
})
ViewPersonResponse entityToViewResponse(PersonEntity source);
  • 23
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝影铁哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值