日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

干掉 BeanUtils!试试这款 Bean 自动映射工具,真心强大!

發(fā)布時(shí)間:2025/3/15 编程问答 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 干掉 BeanUtils!试试这款 Bean 自动映射工具,真心强大! 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

平時(shí)做項(xiàng)目的時(shí)候,經(jīng)常需要做PO、VO、DTO之間的轉(zhuǎn)換。簡(jiǎn)單的對(duì)象轉(zhuǎn)換,使用BeanUtils基本上是夠了,但是復(fù)雜的轉(zhuǎn)換,如果使用它的話又得寫(xiě)一堆Getter、Setter方法了。今天給大家推薦一款對(duì)象自動(dòng)映射工具M(jìn)apStruct,功能真心強(qiáng)大!

?

關(guān)于BeanUtils

平時(shí)我經(jīng)常使用Hutool中的BeanUtil類(lèi)來(lái)實(shí)現(xiàn)對(duì)象轉(zhuǎn)換,用多了之后就發(fā)現(xiàn)有些缺點(diǎn):

  • 對(duì)象屬性映射使用反射來(lái)實(shí)現(xiàn),性能比較低;

  • 對(duì)于不同名稱或不同類(lèi)型的屬性無(wú)法轉(zhuǎn)換,還得單獨(dú)寫(xiě)Getter、Setter方法;

  • 對(duì)于嵌套的子對(duì)象也需要轉(zhuǎn)換的情況,也得自行處理;

  • 集合對(duì)象轉(zhuǎn)換時(shí),得使用循環(huán),一個(gè)個(gè)拷貝。

對(duì)于這些不足,MapStruct都能解決,不愧為一款功能強(qiáng)大的對(duì)象映射工具!

?

MapStruct簡(jiǎn)介

MapStruct是一款基于Java注解的對(duì)象屬性映射工具,在Github上已經(jīng)有4.5K+Star。使用的時(shí)候我們只要在接口中定義好對(duì)象屬性映射規(guī)則,它就能自動(dòng)生成映射實(shí)現(xiàn)類(lèi),不使用反射,性能優(yōu)秀,能實(shí)現(xiàn)各種復(fù)雜映射。

?

IDEA插件支持

作為一款非常流行的對(duì)象映射工具,MapStruct還提供了專(zhuān)門(mén)的IDEA插件,我們?cè)谑褂弥翱梢韵劝惭b好插件。

項(xiàng)目集成

在SpingBoot中集成MapStruct非常簡(jiǎn)單,僅續(xù)添加如下兩個(gè)依賴即可,這里使用的是1.4.2.Final版本。

<dependency><!--MapStruct相關(guān)依賴--><dependency><groupId>org.mapstruct</groupId><artifactId>mapstruct</artifactId><version>${mapstruct.version}</version></dependency><dependency><groupId>org.mapstruct</groupId><artifactId>mapstruct-processor</artifactId><version>${mapstruct.version}</version><scope>compile</scope></dependency> </dependencies>

?

基本使用

集成完MapStruct之后,我們來(lái)體驗(yàn)下它的功能吧,看看它有何神奇之處!

基本映射

我們先來(lái)個(gè)快速入門(mén),體驗(yàn)一下MapStruct的基本功能,并聊聊它的實(shí)現(xiàn)原理。

  • 首先我們準(zhǔn)備好要使用的會(huì)員PO對(duì)象Member;

/***?購(gòu)物會(huì)員*?Created?by?macro?on?2021/10/12.*/ @Data @EqualsAndHashCode(callSuper?=?false) public?class?Member?{private?Long?id;private?String?username;private?String?password;private?String?nickname;private?Date?birthday;private?String?phone;private?String?icon;private?Integer?gender; }
  • 然后再準(zhǔn)備好會(huì)員的DTO對(duì)象MemberDto,我們需要將Member對(duì)象轉(zhuǎn)換為MemberDto對(duì)象;

/***?購(gòu)物會(huì)員Dto*?Created?by?macro?on?2021/10/12.*/ @Data @EqualsAndHashCode(callSuper?=?false) public?class?MemberDto?{private?Long?id;private?String?username;private?String?password;private?String?nickname;//與PO類(lèi)型不同的屬性private?String?birthday;//與PO名稱不同的屬性private?String?phoneNumber;private?String?icon;private?Integer?gender; }
  • 然后創(chuàng)建一個(gè)映射接口MemberMapper,實(shí)現(xiàn)同名同類(lèi)型屬性、不同名稱屬性、不同類(lèi)型屬性的映射;

/***?會(huì)員對(duì)象映射*?Created?by?macro?on?2021/10/21.*/ @Mapper public?interface?MemberMapper?{MemberMapper?INSTANCE?=?Mappers.getMapper(MemberMapper.class);@Mapping(source?=?"phone",target?=?"phoneNumber")@Mapping(source?=?"birthday",target?=?"birthday",dateFormat?=?"yyyy-MM-dd")MemberDto?toDto(Member?member); }
  • 接下來(lái)在Controller中創(chuàng)建測(cè)試接口,直接通過(guò)接口中的INSTANCE實(shí)例調(diào)用轉(zhuǎn)換方法toDto;

/***?MapStruct對(duì)象轉(zhuǎn)換測(cè)試Controller*?Created?by?macro?on?2021/10/21.*/ @RestController @Api(tags?=?"MapStructController",?description?=?"MapStruct對(duì)象轉(zhuǎn)換測(cè)試") @RequestMapping("/mapStruct") public?class?MapStructController?{@ApiOperation(value?=?"基本映射")@GetMapping("/baseMapping")public?CommonResult?baseTest()?{List<Member>?memberList?=?LocalJsonUtil.getListFromJson("json/members.json",?Member.class);MemberDto?memberDto?=?MemberMapper.INSTANCE.toDto(memberList.get(0));return?CommonResult.success(memberDto);} }
  • 運(yùn)行項(xiàng)目后在Swagger中測(cè)試接口,發(fā)現(xiàn)PO所有屬性已經(jīng)成功轉(zhuǎn)換到DTO中去了,Swagger訪問(wèn)地址:http://localhost:8088/swagger-ui

  • 其實(shí)MapStruct的實(shí)現(xiàn)原理很簡(jiǎn)單,就是根據(jù)我們?cè)贛apper接口中使用的@Mapper和@Mapping等注解,在運(yùn)行時(shí)生成接口的實(shí)現(xiàn)類(lèi),我們可以打開(kāi)項(xiàng)目的target目錄看下;

  • 下面是MapStruct為MemberMapper生成好的對(duì)象映射代碼,可以和手寫(xiě)Getter、Setter說(shuō)再見(jiàn)了!

public?class?MemberMapperImpl?implements?MemberMapper?{public?MemberMapperImpl()?{}public?MemberDto?toDto(Member?member)?{if?(member?==?null)?{return?null;}?else?{MemberDto?memberDto?=?new?MemberDto();memberDto.setPhoneNumber(member.getPhone());if?(member.getBirthday()?!=?null)?{memberDto.setBirthday((new?SimpleDateFormat("yyyy-MM-dd")).format(member.getBirthday()));}memberDto.setId(member.getId());memberDto.setUsername(member.getUsername());memberDto.setPassword(member.getPassword());memberDto.setNickname(member.getNickname());memberDto.setIcon(member.getIcon());memberDto.setGender(member.getGender());return?memberDto;}} }

集合映射

MapStruct也提供了集合映射的功能,可以直接將一個(gè)PO列表轉(zhuǎn)換為一個(gè)DTO列表,再也不用一個(gè)個(gè)對(duì)象轉(zhuǎn)換了!

  • 在MemberMapper接口中添加toDtoList方法用于列表轉(zhuǎn)換;

/***?會(huì)員對(duì)象映射*?Created?by?macro?on?2021/10/21.*/ @Mapper public?interface?MemberMapper?{MemberMapper?INSTANCE?=?Mappers.getMapper(MemberMapper.class);@Mapping(source?=?"phone",target?=?"phoneNumber")@Mapping(source?=?"birthday",target?=?"birthday",dateFormat?=?"yyyy-MM-dd")List<MemberDto>?toDtoList(List<Member>?list); }
  • 在Controller中創(chuàng)建測(cè)試接口,直接通過(guò)Mapper接口中的INSTANCE實(shí)例調(diào)用轉(zhuǎn)換方法toDtoList;

/***?MapStruct對(duì)象轉(zhuǎn)換測(cè)試Controller*?Created?by?macro?on?2021/10/21.*/ @RestController @Api(tags?=?"MapStructController",?description?=?"MapStruct對(duì)象轉(zhuǎn)換測(cè)試") @RequestMapping("/mapStruct") public?class?MapStructController?{@ApiOperation(value?=?"集合映射")@GetMapping("/collectionMapping")public?CommonResult?collectionMapping()?{List<Member>?memberList?=?LocalJsonUtil.getListFromJson("json/members.json",?Member.class);List<MemberDto>?memberDtoList?=?MemberMapper.INSTANCE.toDtoList(memberList);return?CommonResult.success(memberDtoList);} }
  • 在Swagger中調(diào)用接口測(cè)試下,PO列表已經(jīng)轉(zhuǎn)換為DTO列表了。

子對(duì)象映射

MapStruct對(duì)于對(duì)象中包含子對(duì)象也需要轉(zhuǎn)換的情況也是有所支持的。

  • 例如我們有一個(gè)訂單PO對(duì)象Order,嵌套有Member和Product對(duì)象;

/***?訂單*?Created?by?macro?on?2021/10/12.*/ @Data @EqualsAndHashCode(callSuper?=?false) public?class?Order?{private?Long?id;private?String?orderSn;private?Date?createTime;private?String?receiverAddress;private?Member?member;private?List<Product>?productList; }
  • 我們需要轉(zhuǎn)換為OrderDto對(duì)象,OrderDto中包含MemberDto和ProductDto兩個(gè)子對(duì)象同樣需要轉(zhuǎn)換;

/***?訂單Dto*?Created?by?macro?on?2021/10/12.*/ @Data @EqualsAndHashCode(callSuper?=?false) public?class?OrderDto?{private?Long?id;private?String?orderSn;private?Date?createTime;private?String?receiverAddress;//子對(duì)象映射Dtoprivate?MemberDto?memberDto;//子對(duì)象數(shù)組映射Dtoprivate?List<ProductDto>?productDtoList; }
  • 我們只需要?jiǎng)?chuàng)建一個(gè)Mapper接口,然后通過(guò)使用uses將子對(duì)象的轉(zhuǎn)換Mapper注入進(jìn)來(lái),然后通過(guò)@Mapping設(shè)置好屬性映射規(guī)則即可;

/***?訂單對(duì)象映射*?Created?by?macro?on?2021/10/21.*/ @Mapper(uses?=?{MemberMapper.class,ProductMapper.class}) public?interface?OrderMapper?{OrderMapper?INSTANCE?=?Mappers.getMapper(OrderMapper.class);@Mapping(source?=?"member",target?=?"memberDto")@Mapping(source?=?"productList",target?=?"productDtoList")OrderDto?toDto(Order?order); }
  • 接下來(lái)在Controller中創(chuàng)建測(cè)試接口,直接通過(guò)Mapper中的INSTANCE實(shí)例調(diào)用轉(zhuǎn)換方法toDto;

/***?MapStruct對(duì)象轉(zhuǎn)換測(cè)試Controller*?Created?by?macro?on?2021/10/21.*/ @RestController @Api(tags?=?"MapStructController",?description?=?"MapStruct對(duì)象轉(zhuǎn)換測(cè)試") @RequestMapping("/mapStruct") public?class?MapStructController?{@ApiOperation(value?=?"子對(duì)象映射")@GetMapping("/subMapping")public?CommonResult?subMapping()?{List<Order>?orderList?=?getOrderList();OrderDto?orderDto?=?OrderMapper.INSTANCE.toDto(orderList.get(0));return?CommonResult.success(orderDto);} }
  • 在Swagger中調(diào)用接口測(cè)試下,可以發(fā)現(xiàn)子對(duì)象屬性已經(jīng)被轉(zhuǎn)換了。

合并映射

MapStruct也支持把多個(gè)對(duì)象屬性映射到一個(gè)對(duì)象中去。

  • 例如這里把Member和Order的部分屬性映射到MemberOrderDto中去;

/***?會(huì)員商品信息組合Dto*?Created?by?macro?on?2021/10/21.*/ @Data @EqualsAndHashCode(callSuper?=?false) public?class?MemberOrderDto?extends?MemberDto{private?String?orderSn;private?String?receiverAddress; }
  • 然后在Mapper中添加toMemberOrderDto方法,這里需要注意的是由于參數(shù)中具有兩個(gè)屬性,需要通過(guò)參數(shù)名稱.屬性的名稱來(lái)指定source來(lái)防止沖突(這兩個(gè)參數(shù)中都有id屬性);

/***?會(huì)員對(duì)象映射*?Created?by?macro?on?2021/10/21.*/ @Mapper public?interface?MemberMapper?{MemberMapper?INSTANCE?=?Mappers.getMapper(MemberMapper.class);@Mapping(source?=?"member.phone",target?=?"phoneNumber")@Mapping(source?=?"member.birthday",target?=?"birthday",dateFormat?=?"yyyy-MM-dd")@Mapping(source?=?"member.id",target?=?"id")@Mapping(source?=?"order.orderSn",?target?=?"orderSn")@Mapping(source?=?"order.receiverAddress",?target?=?"receiverAddress")MemberOrderDto?toMemberOrderDto(Member?member,?Order?order); }
  • 接下來(lái)在Controller中創(chuàng)建測(cè)試接口,直接通過(guò)Mapper中的INSTANCE實(shí)例調(diào)用轉(zhuǎn)換方法toMemberOrderDto;

/***?MapStruct對(duì)象轉(zhuǎn)換測(cè)試Controller*?Created?by?macro?on?2021/10/21.*/ @RestController @Api(tags?=?"MapStructController",?description?=?"MapStruct對(duì)象轉(zhuǎn)換測(cè)試") @RequestMapping("/mapStruct") public?class?MapStructController?{@ApiOperation(value?=?"組合映射")@GetMapping("/compositeMapping")public?CommonResult?compositeMapping()?{List<Order>?orderList?=?LocalJsonUtil.getListFromJson("json/orders.json",?Order.class);List<Member>?memberList?=?LocalJsonUtil.getListFromJson("json/members.json",?Member.class);Member?member?=?memberList.get(0);Order?order?=?orderList.get(0);MemberOrderDto?memberOrderDto?=?MemberMapper.INSTANCE.toMemberOrderDto(member,order);return?CommonResult.success(memberOrderDto);} }
  • 在Swagger中調(diào)用接口測(cè)試下,可以發(fā)現(xiàn)Member和Order中的屬性已經(jīng)被映射到MemberOrderDto中去了。

進(jìn)階使用

通過(guò)上面的基本使用,大家已經(jīng)可以玩轉(zhuǎn)MapStruct了,下面我們?cè)賮?lái)介紹一些進(jìn)階的用法。

使用依賴注入

上面我們都是通過(guò)Mapper接口中的INSTANCE實(shí)例來(lái)調(diào)用方法的,在Spring中我們也是可以使用依賴注入的。

  • 想要使用依賴注入,我們只要將@Mapper注解的componentModel參數(shù)設(shè)置為spring即可,這樣在生成接口實(shí)現(xiàn)類(lèi)時(shí),MapperStruct會(huì)為其添加@Component注解;

/***?會(huì)員對(duì)象映射(依賴注入)*?Created?by?macro?on?2021/10/21.*/ @Mapper(componentModel?=?"spring") public?interface?MemberSpringMapper?{@Mapping(source?=?"phone",target?=?"phoneNumber")@Mapping(source?=?"birthday",target?=?"birthday",dateFormat?=?"yyyy-MM-dd")MemberDto?toDto(Member?member); }
  • 接下來(lái)在Controller中使用@Autowired注解注入即可使用;

/***?MapStruct對(duì)象轉(zhuǎn)換測(cè)試Controller*?Created?by?macro?on?2021/10/21.*/ @RestController @Api(tags?=?"MapStructController",?description?=?"MapStruct對(duì)象轉(zhuǎn)換測(cè)試") @RequestMapping("/mapStruct") public?class?MapStructController?{@Autowiredprivate?MemberSpringMapper?memberSpringMapper;@ApiOperation(value?=?"使用依賴注入")@GetMapping("/springMapping")public?CommonResult?springMapping()?{List<Member>?memberList?=?LocalJsonUtil.getListFromJson("json/members.json",?Member.class);MemberDto?memberDto?=?memberSpringMapper.toDto(memberList.get(0));return?CommonResult.success(memberDto);} }
  • 在Swagger中調(diào)用接口測(cè)試下,可以發(fā)現(xiàn)與之前一樣可以正常使用。

使用常量、默認(rèn)值和表達(dá)式

使用MapStruct映射屬性時(shí),我們可以設(shè)置屬性為常量或者默認(rèn)值,也可以通過(guò)Java中的方法編寫(xiě)表達(dá)式來(lái)自動(dòng)生成屬性。

  • 例如下面這個(gè)商品類(lèi)Product對(duì)象;

/***?商品*?Created?by?macro?on?2021/10/12.*/ @Data @EqualsAndHashCode(callSuper?=?false) public?class?Product?{private?Long?id;private?String?productSn;private?String?name;private?String?subTitle;private?String?brandName;private?BigDecimal?price;private?Integer?count;private?Date?createTime; }
  • 我們想把Product轉(zhuǎn)換為ProductDto對(duì)象,id屬性設(shè)置為常量,count設(shè)置默認(rèn)值為1,productSn設(shè)置為UUID生成;

/***?商品Dto*?Created?by?macro?on?2021/10/12.*/ @Data @EqualsAndHashCode(callSuper?=?false) public?class?ProductDto?{//使用常量private?Long?id;//使用表達(dá)式生成屬性private?String?productSn;private?String?name;private?String?subTitle;private?String?brandName;private?BigDecimal?price;//使用默認(rèn)值private?Integer?count;private?Date?createTime; }
  • 創(chuàng)建ProductMapper接口,通過(guò)@Mapping注解中的constant、defaultValue、expression設(shè)置好映射規(guī)則;

/***?商品對(duì)象映射*?Created?by?macro?on?2021/10/21.*/ @Mapper(imports?=?{UUID.class}) public?interface?ProductMapper?{ProductMapper?INSTANCE?=?Mappers.getMapper(ProductMapper.class);@Mapping(target?=?"id",constant?=?"-1L")@Mapping(source?=?"count",target?=?"count",defaultValue?=?"1")@Mapping(target?=?"productSn",expression?=?"java(UUID.randomUUID().toString())")ProductDto?toDto(Product?product); }
  • 接下來(lái)在Controller中創(chuàng)建測(cè)試接口,直接通過(guò)接口中的INSTANCE實(shí)例調(diào)用轉(zhuǎn)換方法toDto;

/***?MapStruct對(duì)象轉(zhuǎn)換測(cè)試Controller*?Created?by?macro?on?2021/10/21.*/ @RestController @Api(tags?=?"MapStructController",?description?=?"MapStruct對(duì)象轉(zhuǎn)換測(cè)試") @RequestMapping("/mapStruct") public?class?MapStructController?{@ApiOperation(value?=?"使用常量、默認(rèn)值和表達(dá)式")@GetMapping("/defaultMapping")public?CommonResult?defaultMapping()?{List<Product>?productList?=?LocalJsonUtil.getListFromJson("json/products.json",?Product.class);Product?product?=?productList.get(0);product.setId(100L);product.setCount(null);ProductDto?productDto?=?ProductMapper.INSTANCE.toDto(product);return?CommonResult.success(productDto);} }
  • 在Swagger中調(diào)用接口測(cè)試下,對(duì)象已經(jīng)成功轉(zhuǎn)換。

在映射前后進(jìn)行自定義處理

MapStruct也支持在映射前后做一些自定義操作,類(lèi)似AOP中的切面。

  • 由于此時(shí)我們需要?jiǎng)?chuàng)建自定義處理方法,創(chuàng)建一個(gè)抽象類(lèi)ProductRoundMapper,通過(guò)@BeforeMapping注解自定義映射前操作,通過(guò)@AfterMapping注解自定義映射后操作;

/***?商品對(duì)象映射(自定義處理)*?Created?by?macro?on?2021/10/21.*/ @Mapper(imports?=?{UUID.class}) public?abstract?class?ProductRoundMapper?{public?static?ProductRoundMapper?INSTANCE?=?Mappers.getMapper(ProductRoundMapper.class);@Mapping(target?=?"id",constant?=?"-1L")@Mapping(source?=?"count",target?=?"count",defaultValue?=?"1")@Mapping(target?=?"productSn",expression?=?"java(UUID.randomUUID().toString())")public?abstract?ProductDto?toDto(Product?product);@BeforeMappingpublic?void?beforeMapping(Product?product){//映射前當(dāng)price<0時(shí)設(shè)置為0if(product.getPrice().compareTo(BigDecimal.ZERO)<0){product.setPrice(BigDecimal.ZERO);}}@AfterMappingpublic?void?afterMapping(@MappingTarget?ProductDto?productDto){//映射后設(shè)置當(dāng)前時(shí)間為createTimeproductDto.setCreateTime(new?Date());} }
  • 接下來(lái)在Controller中創(chuàng)建測(cè)試接口,直接通過(guò)Mapper中的INSTANCE實(shí)例調(diào)用轉(zhuǎn)換方法toDto;

/***?MapStruct對(duì)象轉(zhuǎn)換測(cè)試Controller*?Created?by?macro?on?2021/10/21.*/ @RestController @Api(tags?=?"MapStructController",?description?=?"MapStruct對(duì)象轉(zhuǎn)換測(cè)試") @RequestMapping("/mapStruct") public?class?MapStructController?{@ApiOperation(value?=?"在映射前后進(jìn)行自定義處理")@GetMapping("/customRoundMapping")public?CommonResult?customRoundMapping()?{List<Product>?productList?=?LocalJsonUtil.getListFromJson("json/products.json",?Product.class);Product?product?=?productList.get(0);product.setPrice(new?BigDecimal(-1));ProductDto?productDto?=?ProductRoundMapper.INSTANCE.toDto(product);return?CommonResult.success(productDto);} }
  • 在Swagger中調(diào)用接口測(cè)試下,可以發(fā)現(xiàn)已經(jīng)應(yīng)用了自定義操作。

處理映射異常

代碼運(yùn)行難免會(huì)出現(xiàn)異常,MapStruct也支持處理映射異常。

  • 我們需要先創(chuàng)建一個(gè)自定義異常類(lèi);

/***?商品驗(yàn)證異常類(lèi)*?Created?by?macro?on?2021/10/22.*/ public?class?ProductValidatorException?extends?Exception{public?ProductValidatorException(String?message)?{super(message);} }
  • 然后創(chuàng)建一個(gè)驗(yàn)證類(lèi),當(dāng)price設(shè)置小于0時(shí)拋出我們自定義的異常;

/***?商品驗(yàn)證異常處理器*?Created?by?macro?on?2021/10/22.*/ public?class?ProductValidator?{public?BigDecimal?validatePrice(BigDecimal?price)?throws?ProductValidatorException?{if(price.compareTo(BigDecimal.ZERO)<0){throw?new?ProductValidatorException("價(jià)格不能小于0!");}return?price;} }
  • 之后我們通過(guò)@Mapper注解的uses屬性運(yùn)用驗(yàn)證類(lèi);

/***?商品對(duì)象映射(處理映射異常)*?Created?by?macro?on?2021/10/21.*/ @Mapper(uses?=?{ProductValidator.class},imports?=?{UUID.class}) public?interface?ProductExceptionMapper?{ProductExceptionMapper?INSTANCE?=?Mappers.getMapper(ProductExceptionMapper.class);@Mapping(target?=?"id",constant?=?"-1L")@Mapping(source?=?"count",target?=?"count",defaultValue?=?"1")@Mapping(target?=?"productSn",expression?=?"java(UUID.randomUUID().toString())")ProductDto?toDto(Product?product)?throws?ProductValidatorException; }
  • 然后在Controller中添加測(cè)試接口,設(shè)置price為-1,此時(shí)在進(jìn)行映射時(shí)會(huì)拋出異常;

/***?MapStruct對(duì)象轉(zhuǎn)換測(cè)試Controller*?Created?by?macro?on?2021/10/21.*/ @RestController @Api(tags?=?"MapStructController",?description?=?"MapStruct對(duì)象轉(zhuǎn)換測(cè)試") @RequestMapping("/mapStruct") public?class?MapStructController?{@ApiOperation(value?=?"處理映射異常")@GetMapping("/exceptionMapping")public?CommonResult?exceptionMapping()?{List<Product>?productList?=?LocalJsonUtil.getListFromJson("json/products.json",?Product.class);Product?product?=?productList.get(0);product.setPrice(new?BigDecimal(-1));ProductDto?productDto?=?null;try?{productDto?=?ProductExceptionMapper.INSTANCE.toDto(product);}?catch?(ProductValidatorException?e)?{e.printStackTrace();}return?CommonResult.success(productDto);} }
  • 在Swagger中調(diào)用接口測(cè)試下,發(fā)現(xiàn)運(yùn)行日志中已經(jīng)打印了自定義異常信息。

總結(jié)

通過(guò)上面對(duì)MapStruct的使用體驗(yàn),我們可以發(fā)現(xiàn)MapStruct遠(yuǎn)比BeanUtils要強(qiáng)大。當(dāng)我們想實(shí)現(xiàn)比較復(fù)雜的對(duì)象映射時(shí),通過(guò)它可以省去寫(xiě)Getter、Setter方法的過(guò)程。當(dāng)然上面只是介紹了MapStruct的一些常用功能,它的功能遠(yuǎn)不止于此,感興趣的朋友可以查看下官方文檔。

參考資料

官方文檔:https://mapstruct.org/documentation/stable/reference/html

項(xiàng)目源碼地址

https://github.com/macrozheng/mall-learning/tree/master/mall-tiny-mapstruct

有道無(wú)術(shù),術(shù)可成;有術(shù)無(wú)道,止于術(shù)

歡迎大家關(guān)注Java之道公眾號(hào)

好文章,我在看??

總結(jié)

以上是生活随笔為你收集整理的干掉 BeanUtils!试试这款 Bean 自动映射工具,真心强大!的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。