Java高性能实体类转换工具MapStruct的使用教程详解

 更新时间:2024年03月24日 10:02:06   作者:EvenBoy  
MapStruct 是一个代码生成器,它基于约定优于配置的方法,极大地简化了 Java bean 类型之间的映射实现,本文主要介绍了MapStruct的具体使用以及如何进行实体类转换,感兴趣的可以了解下

MapStruct

它是什么?

MapStruct 是一个代码生成器,它基于约定优于配置的方法,极大地简化了 Java bean 类型之间的映射实现。

生成的映射代码使用普通的方法调用,因此速度快、类型安全且易于理解。

为什么?

多层应用程序通常需要在不同的对象模型(例如实体和 DTO)之间进行映射。编写这样的映射代码是一项乏味且容易出错的任务。MapStruct 旨在通过尽可能地自动化来简化这项工作。

与其他映射框架相比,MapStruct 在编译时生成 bean 映射,这确保了高性能,允许快速的开发人员反馈和彻底的错误检查。

如何?

MapStruct 是一个注解处理器,它插入到 Java 编译器中,可用于命令行构建(Maven、Gradle 等)以及您首选的 IDE。

MapStruct 使用合理的默认值,但在配置或实现特殊行为时会采取措施。

使用场景

1、数据库中的字段和你对接的A部门、B部门的入参字段不一致的情况。

2、涉及到一些入参和出参值的转换 比如:性别、日期等。

使用教程

1、引入pom.xml

     <!--mapStruct依赖-->
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>1.3.1.Final</version>
        </dependency>
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct-processor</artifactId>
            <version>1.3.1.Final</version>
            <scope>provided</scope>
        </dependency>

2、入参(每个部门的入参可能不太一样)

package com.lezu.springboot.common.dto.param;
 
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
 
/**
 * @author LianJiaYu
 * @date 2022/9/1 14:09
 */
@Data
public class UserInfoParam {
 
    @ApiModelProperty(value = "用户账号")
    private String account;
 
    @ApiModelProperty(value = "性别")
    private String gender;
 
    @ApiModelProperty(value = "密码")
    private String password;
 
    @ApiModelProperty(value = "出生日期")
    private Long birthday;
 
    @ApiModelProperty(value = "验证码captchaId")
    private String captchaId;
 
    @ApiModelProperty(value = "昵称")
    private String name;
 
    @ApiModelProperty(value = "验证码")
    private String code;
 
}

3、对应数据库中的字段

package com.lezu.springboot.common.dto.in;
 
import com.lezu.springboot.common.Page;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
 
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.Date;
 
/**
 * @Author LianJiaYu
 * @Date 2021/4/4 22:06
 * @Version 1.0
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class InUserInfoDto extends Page implements Serializable {
 
    private static final long serialVersionUID = 5755742614532104337L;
 
    @ApiModelProperty(value = "用户账号")
    @NotNull(message = "用户名不能为空")
    private String username;
 
    @ApiModelProperty(value = "性别")
    private Integer gender;
 
    @ApiModelProperty(value = "密码")
    @NotNull(message = "密码不能为空")
    private String password;
 
    @ApiModelProperty(value = "出生日期")
    private Date birthday;
 
    @ApiModelProperty(value = "验证码captchaId")
    private String captchaId;
 
    @ApiModelProperty(value = "昵称")
    private String name;
 
    @ApiModelProperty(value = "验证码")
    private String code;
 
    @ApiModelProperty(value = "默认状态")
    private String defaultStatus;
 
}

4、定义工厂

package com.lezu.springboot.common.dto.Interface;
 
import com.lezu.springboot.common.ListResult;
import com.lezu.springboot.common.conversion.DataConversionWorker;
import com.lezu.springboot.common.conversion.EnumConversionWorker;
import com.lezu.springboot.common.dto.in.InUserInfoDto;
import com.lezu.springboot.common.dto.out.OutUserInfoDto;
import com.lezu.springboot.common.dto.param.UserInfoParam;
import com.lezu.springboot.common.dto.result.UserInfoResult;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
 
/**
 * @author LianJiaYu
 * @date 2022/9/1 14:04
 */
@Mapper(uses = {DataConversionWorker.class, EnumConversionWorker.class})
public interface UserConvert {
    UserConvert INSTANCE = Mappers.getMapper(UserConvert.class);
 
 
    //入参转换
    @Mappings({
            @Mapping(source = "account", target = "username"),
            @Mapping(source = "gender", target = "gender", qualifiedByName = "setGenderToInteger"),
            @Mapping(source = "birthday", target = "birthday", qualifiedByName = "getBirthdayToDate"),
            @Mapping(target = "defaultStatus", defaultValue = "success"),
    })
    InUserInfoDto userInfoConvert(UserInfoParam param);
 
 
    //出参转换
    @Mappings({
            @Mapping(source = "username", target = "account"),
            @Mapping(source = "gender", target = "gender", qualifiedByName = "setGenderToString"),
            @Mapping(source = "birthday", target = "birthday", qualifiedByName = "getBirthdayToLong"),
    })
    UserInfoResult userInfoResultConvert(OutUserInfoDto dto);
 
    ListResult<UserInfoResult> listUserInfoResultConvert(ListResult<OutUserInfoDto> list);
 
 
}

5、定义时间戳转换日期和日期转时间戳方法

package com.lezu.springboot.common.conversion;
 
import cn.hutool.core.date.DateUtil;
import org.mapstruct.Named;
 
import java.util.Date;
 
/**
 * @author LianJiaYu
 * @date 2022/9/2 15:08
 */
//@Component
public class DataConversionWorker {
 
    @Named("getBirthdayToDate")
    public Date getBirthdayToDate(Long birthday) {
        if (birthday == null) {
            return null;
        }
        return DateUtil.date(birthday);
    }
 
    @Named("getBirthdayToLong")
    public Long getBirthdayToLong(Date birthday) {
        if (birthday == null) {
            return null;
        }
        return birthday.getTime();
    }
}

6、定义性别转换方法

package com.lezu.springboot.common.conversion;
 
import com.lezu.springboot.enums.UserGenderEnum;
import org.mapstruct.Named;
import org.springframework.stereotype.Component;
 
/**
 * @author LianJiaYu
 * @date 2022/9/2 15:08
 */
//@Component
public class EnumConversionWorker {
 
    @Named("setGenderToInteger")
    public Integer setGenderToInteger(String type) {
        return UserGenderEnum.getByType(type).getCode();
    }
 
    @Named("setGenderToString")
    public Integer setGenderToString(Integer code) {
        return UserGenderEnum.getByCode(code).getCode();
    }
 
}

7、性别转换枚举

package com.lezu.springboot.enums;
 
/**
 * @author LianJiaYu
 * @date 2022/9/16 10:10
 */
public enum UserGenderEnum {
    FEMALE(0, "female"),
    MALE(1, "male"),
    UNKNOWN(2, "unknown"),
    ;
 
 
    private Integer code;
    private String type;
 
    UserGenderEnum(Integer code, String type) {
        this.code = code;
        this.type = type;
    }
 
    public Integer getCode() {
        return code;
    }
 
    public String getType() {
        return type;
    }
 
 
    public static UserGenderEnum getByCode(Integer code) {
        for (UserGenderEnum v : UserGenderEnum.values()) {
            if (v.getCode() == code) {
                return v;
            }
        }
        return UNKNOWN;
    }
 
    public static UserGenderEnum getByType(String type) {
        for (UserGenderEnum v : UserGenderEnum.values()) {
            if (v.getType().equals(type)) {
                return v;
            }
        }
        return UNKNOWN;
    }
}

8、编写Controller代码进行测试

package com.lezu.springboot.controller;
 
import com.alibaba.fastjson.JSON;
import com.lezu.springboot.common.ListResult;
import com.lezu.springboot.common.dto.Interface.UserConvert;
import com.lezu.springboot.common.dto.in.InUserInfoDto;
import com.lezu.springboot.common.dto.param.UserInfoParam;
import com.lezu.springboot.common.dto.result.UserInfoResult;
import com.lezu.springboot.enums.ResultEnum;
import com.lezu.springboot.service.UserInfoHandleService;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
import java.util.Objects;
 
/**
 * 高性能实体类转换工具MapStruct
 * 类型转换工具
 * @author LianJiaYu
 * @date 2022/9/1 13:57
 */
@RestController
@RequestMapping("/mapstruct")
@Slf4j
public class MapstructController {
 
    @Autowired
    private UserInfoHandleService userInfoHandleService;
 
    @ApiOperation("类型转换")
    @PostMapping("/login")
    public ListResult<UserInfoResult> login(UserInfoParam params) {
        ListResult listResult = new ListResult();
        if (Objects.isNull(params)) {
            return listResult.build(ResultEnum.PARAM_ERROR.getCode(), ResultEnum.PARAM_ERROR.getMsg());
        }
        //入参-日志
        log.info("params:" + JSON.toJSONString(params));
 
        //入参-参数转换
        InUserInfoDto inDto = UserConvert.INSTANCE.userInfoConvert(params);
        log.info("inDto:" + JSON.toJSONString(inDto));
 
 
        //出参-参数转换
        listResult = UserConvert.INSTANCE.outDtoToResult(userInfoHandleService.listByPage(inDto));
        log.info("listResult:" + JSON.toJSONString(listResult));
        return listResult;
    }
}

Service层

   @Override
    public ListResult listByPage(InUserInfoDto inDto) {
        ListResult listResult = new ListResult();
        LambdaQueryWrapper<UserInfo> wrapper = Wrappers.lambdaQuery();
        if (StrUtil.isNotBlank(inDto.getUsername())) {
            wrapper.like(UserInfo::getUsername, inDto.getUsername());
        }
        int pageNum = inDto.getPageNum();
        int pageSize = inDto.getPageSize() == 0 ? 10 : inDto.getPageSize();
 
        IPage<UserInfo> page = new Page<>(pageNum, pageSize);
        userInfoService.page(page, wrapper);
        List<OutUserInfoDto> list = page.getRecords().stream().map(v -> {
            OutUserInfoDto dto = new OutUserInfoDto();
            BeanUtils.copyProperties(v, dto);
            return dto;
        }).collect(Collectors.toList());
 
 
        return listResult.ok(list, page.getTotal());
    }

OutUserInfo实体类

package com.lezu.springboot.common.dto.out;
 
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
 
import java.io.Serializable;
 
/**
 * @Author LianJiaYu
 * @Date 2021/4/4 22:06
 * @Version 1.0
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class OutUserInfoDto implements Serializable {
 
    private static final long serialVersionUID = 6248490570574329534L;
 
    @ApiModelProperty(value = "主键id")
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
 
    @ApiModelProperty(value = "用户账号")
    private String username;
 
    @ApiModelProperty(value = "性别")
    private String gender;
 
    @ApiModelProperty(value = "密码")
    private String password;
 
    @ApiModelProperty(value = "权限")
    private Integer power;
 
    @ApiModelProperty(value = "昵称")
    private String name;
 
 
 
}

以上就是Java高性能实体类转换工具MapStruct的使用教程详解的详细内容,更多关于Java MapStruct实体类转换的资料请关注脚本之家其它相关文章!

相关文章

  • xxl-job在 Spring Boot 项目中的完整配置指南(最新整理)

    xxl-job在 Spring Boot 项目中的完整配置指南(最新整理)

    本文详细介绍了Spring Boot任务调度配置,包括依赖配置、多环境支持、任务处理器、高级配置、常见问题及解决方法,以及项目结构和注意事项,感兴趣的朋友跟随小编一起看看吧
    2025-12-12
  • JAVA Optional类用法分享

    JAVA Optional类用法分享

    本篇文章主要给大家分析了JAVA中Optional类用法以及代码分析,跟着小编学习下吧。
    2017-12-12
  • Java设计模式之模板方法详解

    Java设计模式之模板方法详解

    模板方法的概念:定义了一个操作中的算法的骨架,而将部分步骤的实现在子类中完成。模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤
    2022-07-07
  • Selenium Webdriver实现截图功能的示例

    Selenium Webdriver实现截图功能的示例

    今天小编就为大家分享一篇Selenium Webdriver实现截图功能的示例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-05-05
  • 深入探究Spring底层核心原理

    深入探究Spring底层核心原理

    理解IOC与AOP的实现机制,优化应用性能与可维护性。Spring通过IOC容器管理Bean,AOP实现切面编程,支持事务管理、ORM框架等。深入理解Spring原理,可以帮助我们更好地使用Spring框架,提高开发效率与质量
    2023-04-04
  • SpringBoot中的自定义starter详解

    SpringBoot中的自定义starter详解

    这篇文章主要介绍了SpringBoot中的自定义starter详解,SpringBoot中的starter是一种非常重要的机制,能够抛弃以前繁杂的配置,将其统一集成进starter,需要的朋友可以参考下
    2024-01-01
  • 基于MyBatis的数据持久化框架的使用详解

    基于MyBatis的数据持久化框架的使用详解

    Mybatis是一个优秀的开源、轻量级持久层框架,它对JDBC操作数据库的过程进行封装。本文将为大家讲解一下基于MyBatis的数据持久化框架的使用,感兴趣的可以了解一下
    2022-08-08
  • Spring的CorsFilter会失效的原因及解决方法

    Spring的CorsFilter会失效的原因及解决方法

    众所周知CorsFilter是Spring提供的跨域过滤器,我们可能会做以下的配置,基本上就是允许任何跨域请求,我利用Spring的CorsFilter做跨域操作但是出现报错,接下来小编就给大家介绍一Spring的CorsFilter会失效的原因及解决方法,需要的朋友可以参考下
    2023-09-09
  • IntelliJ IDEA 2020.2.3永久破解激活教程(亲测有效)

    IntelliJ IDEA 2020.2.3永久破解激活教程(亲测有效)

    intellij idea 2022是一款市面上最好的JAVA IDE编程工具,该工具支持git、svn、github等版本控制工具,整合了智能代码助手、代码自动提示等功能,本教程给大家分享IDEA 2022最新永久激活码,感兴趣的朋友参考下吧
    2020-10-10
  • SpringCloud之Feign代理,声明式服务调用方式

    SpringCloud之Feign代理,声明式服务调用方式

    这篇文章主要介绍了SpringCloud之Feign代理,声明式服务调用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03

最新评论