它是什么?
MapStruct 是一个代码生成器,它基于约定优于配置的方法,极大地简化了 Java bean 类型之间的映射实现。
生成的映射代码使用普通的方法调用,因此速度快、类型安全且易于理解。
为什么?
多层应用程序通常需要在不同的对象模型(例如实体和 DTO)之间进行映射。编写这样的映射代码是一项乏味且容易出错的任务。MapStruct 旨在通过尽可能地自动化来简化这项工作。
与其他映射框架相比,MapStruct 在编译时生成 bean 映射,这确保了高性能,允许快速的开发人员反馈和彻底的错误检查。
如何?
MapStruct 是一个注解处理器,它插入到 Java 编译器中,可用于命令行构建(Maven、Gradle 等)以及您首选的 IDE。
MapStruct 使用合理的默认值,但在配置或实现特殊行为时会采取措施。
1、数据库中的字段和你对接的A部门、B部门的入参字段不一致的情况。
2、涉及到一些入参和出参值的转换 比如:性别、日期等。
1、引入pom.xml
-
- <dependency>
- <groupId>org.mapstructgroupId>
- <artifactId>mapstructartifactId>
- <version>1.3.1.Finalversion>
- dependency>
- <dependency>
- <groupId>org.mapstructgroupId>
- <artifactId>mapstruct-processorartifactId>
- <version>1.3.1.Finalversion>
- <scope>providedscope>
- 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;
-
- }
3、定义工厂
- 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
listUserInfoResultConvert(ListResult list) ; -
-
- }
定义时间戳转换日期和日期转时间戳方法
- 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();
- }
- }
定义性别转换方法
- 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();
- }
-
- }
性别转换枚举
- 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;
- }
- }
- 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
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
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
page = new Page<>(pageNum, pageSize); - userInfoService.page(page, wrapper);
- List
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;
-
-
-
- }