java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java MapStruct实体类转换

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

作者: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实体类转换的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文