Java高性能實體類轉換工具MapStruct的使用教程詳解
MapStruct
它是什么?
MapStruct 是一個代碼生成器,它基于約定優(yōu)于配置的方法,極大地簡化了 Java bean 類型之間的映射實現(xiàn)。
生成的映射代碼使用普通的方法調(diào)用,因此速度快、類型安全且易于理解。
為什么?
多層應用程序通常需要在不同的對象模型(例如實體和 DTO)之間進行映射。編寫這樣的映射代碼是一項乏味且容易出錯的任務。MapStruct 旨在通過盡可能地自動化來簡化這項工作。
與其他映射框架相比,MapStruct 在編譯時生成 bean 映射,這確保了高性能,允許快速的開發(fā)人員反饋和徹底的錯誤檢查。
如何?
MapStruct 是一個注解處理器,它插入到 Java 編譯器中,可用于命令行構建(Maven、Gradle 等)以及您首選的 IDE。
MapStruct 使用合理的默認值,但在配置或?qū)崿F(xiàn)特殊行為時會采取措施。
使用場景
1、數(shù)據(jù)庫中的字段和你對接的A部門、B部門的入?yún)⒆侄尾灰恢碌那闆r。
2、涉及到一些入?yún)⒑统鰠⒅档霓D換 比如:性別、日期等。
使用教程
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、入?yún)?每個部門的入?yún)⒖赡懿惶粯?
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、對應數(shù)據(jù)庫中的字段
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 = "默認狀態(tài)")
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);
//入?yún)⑥D換
@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());
}
//入?yún)?日志
log.info("params:" + JSON.toJSONString(params));
//入?yún)?參數(shù)轉換
InUserInfoDto inDto = UserConvert.INSTANCE.userInfoConvert(params);
log.info("inDto:" + JSON.toJSONString(inDto));
//出參-參數(shù)轉換
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的使用教程詳解的詳細內(nèi)容,更多關于Java MapStruct實體類轉換的資料請關注腳本之家其它相關文章!
相關文章
解決shiro 定時監(jiān)聽器不生效的問題 onExpiration不調(diào)用問題
這篇文章主要介紹了解決shiro 定時監(jiān)聽器不生效的問題 onExpiration不調(diào)用問題。具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07
springboot項目中mybatis-plus@Mapper注入失敗問題
這篇文章主要介紹了springboot項目中mybatis-plus@Mapper注入失敗問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-07-07
Spring boot2X負載均衡和反向代理實現(xiàn)過程解析
這篇文章主要介紹了Spring boot2X負載均衡和反向代理實現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2019-12-12

