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