Java高性能實體類轉(zhuǎn)換工具MapStruct的使用教程詳解
MapStruct
它是什么?
MapStruct 是一個代碼生成器,它基于約定優(yōu)于配置的方法,極大地簡化了 Java bean 類型之間的映射實現(xiàn)。
生成的映射代碼使用普通的方法調(diào)用,因此速度快、類型安全且易于理解。
為什么?
多層應(yīng)用程序通常需要在不同的對象模型(例如實體和 DTO)之間進行映射。編寫這樣的映射代碼是一項乏味且容易出錯的任務(wù)。MapStruct 旨在通過盡可能地自動化來簡化這項工作。
與其他映射框架相比,MapStruct 在編譯時生成 bean 映射,這確保了高性能,允許快速的開發(fā)人員反饋和徹底的錯誤檢查。
如何?
MapStruct 是一個注解處理器,它插入到 Java 編譯器中,可用于命令行構(gòu)建(Maven、Gradle 等)以及您首選的 IDE。
MapStruct 使用合理的默認(rèn)值,但在配置或?qū)崿F(xiàn)特殊行為時會采取措施。
使用場景
1、數(shù)據(jù)庫中的字段和你對接的A部門、B部門的入?yún)⒆侄尾灰恢碌那闆r。
2、涉及到一些入?yún)⒑统鰠⒅档霓D(zhuǎn)換 比如:性別、日期等。
使用教程
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、對應(yīng)數(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 = "默認(rèn)狀態(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(zhuǎn)換
@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);
//出參轉(zhuǎn)換
@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、定義時間戳轉(zhuǎn)換日期和日期轉(zhuǎn)時間戳方法
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、定義性別轉(zhuǎn)換方法
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、性別轉(zhuǎn)換枚舉
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;
/**
* 高性能實體類轉(zhuǎn)換工具MapStruct
* 類型轉(zhuǎn)換工具
* @author LianJiaYu
* @date 2022/9/1 13:57
*/
@RestController
@RequestMapping("/mapstruct")
@Slf4j
public class MapstructController {
@Autowired
private UserInfoHandleService userInfoHandleService;
@ApiOperation("類型轉(zhuǎn)換")
@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ù)轉(zhuǎn)換
InUserInfoDto inDto = UserConvert.INSTANCE.userInfoConvert(params);
log.info("inDto:" + JSON.toJSONString(inDto));
//出參-參數(shù)轉(zhuǎn)換
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 = "權(quán)限")
private Integer power;
@ApiModelProperty(value = "昵稱")
private String name;
}
以上就是Java高性能實體類轉(zhuǎn)換工具MapStruct的使用教程詳解的詳細(xì)內(nèi)容,更多關(guān)于Java MapStruct實體類轉(zhuǎn)換的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
完美解決idea光標(biāo)變成了insert光標(biāo)狀態(tài)的問題
這篇文章主要介紹了完美解決idea光標(biāo)變成了insert光標(biāo)狀態(tài)的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-02-02
利用Spring Cloud Config結(jié)合Bus實現(xiàn)分布式配置中心的步驟
這篇文章主要介紹了利用Spring Cloud Config結(jié)合Bus實現(xiàn)分布式配置中心的相關(guān)資料,文中通過示例代碼將實現(xiàn)的步驟一步步介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友下面來一起看看吧2018-05-05
Spring中任務(wù)調(diào)度之解讀@Scheduled和@Schedules注解的使用
這篇文章主要介紹了Spring中任務(wù)調(diào)度之解讀@Scheduled和@Schedules注解的使用,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-04-04
Java HttpClient-Restful工具各種請求高度封裝提煉及總結(jié)
這篇文章主要介紹了Java HttpClient-Restful工具各種請求高度封裝提煉及總結(jié),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-10-10
java根據(jù)模板實現(xiàn)填充word內(nèi)容并轉(zhuǎn)換為pdf
這篇文章主要為大家詳細(xì)介紹了java如何根據(jù)模板實現(xiàn)填充word內(nèi)容并轉(zhuǎn)換為pdf,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2025-04-04
Spring security BCryptPasswordEncoder密碼驗證原理詳解
這篇文章主要介紹了Spring security BCryptPasswordEncoder密碼驗證原理詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-03-03
MyBatis-Plus使用ActiveRecord(AR)實現(xiàn)CRUD
本文將結(jié)合實例代碼,介紹MyBatis-Plus使用ActiveRecord(AR)實現(xiàn)CRUD,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-07-07

