参考链接:mapstruct的基本使用

背景介绍

是不是有时候发现明明source和target不是同一个类型,但是却转换成功了,这是因为mapstruct有一套自己的类型转换机制

类型转换的流程

  1. 首先尝试自动进行类型转换
  2. 若是无法支持的类型转换,则是尝试调用已经存在的类型转换方法
  3. 不存在可用的方法则是尝试自己创建一个类型转换方法

类型转换分类

自动转换

以下的类型之间是mapstruct自动进行类型转换的。

  • 基本类型及其他们对应的包装类型。
    此时mapstruct会自动进行拆装箱。不需要人为的处理
  • 基本类型的包装类型和string类型之间
@Data
@NoArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
@AllArgsConstructor
public class Item1 {Long itemId;String title;
}@Data
@NoArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
@AllArgsConstructor
public class Item2 {Long itemId;String title;
}@Data
@NoArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
@AllArgsConstructor
public class Sku2 {Long skuId;String skuCode;String skuPrice;List<String> nameList;Item1 item;
}@Data
@NoArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
@AllArgsConstructor
public class SkuDTO2 {Long skuId;String skuCode;Long skuPrice;List<String> nameList;Item2 item;
}@Mapper
public interface ItemConvert {ItemConvert INSTANCE = Mappers.getMapper(ItemConvert.class);SkuDTO2 domain2Dto(Sku2 sku2);
}// 以下为mapstruct自动生成
public class ItemConvertImpl implements ItemConvert {@Overridepublic SkuDTO2 domain2Dto(Sku2 sku2) {if ( sku2 == null ) {return null;}SkuDTO2 skuDTO2 = new SkuDTO2();skuDTO2.setSkuId( sku2.getSkuId() );skuDTO2.setSkuCode( sku2.getSkuCode() );if ( sku2.getSkuPrice() != null ) {skuDTO2.setSkuPrice( Long.parseLong( sku2.getSkuPrice() ) );}List<String> list = sku2.getNameList();if ( list != null ) {skuDTO2.setNameList( new ArrayList<String>( list ) );}skuDTO2.setItem( item1ToItem2( sku2.getItem() ) );return skuDTO2;}protected Item2 item1ToItem2(Item1 item1) {if ( item1 == null ) {return null;}Item2 item2 = new Item2();item2.setItemId( item1.getItemId() );item2.setTitle( item1.getTitle() );return item2;
}
自定义转换类型
  • 使用表达式进行定义类型转换,expression="java(。。。)"
    注意:使用表达式的时候,类必须是全路径的使用,或者@Mapper(imports={类名.class}
@Mapper(imports={DemandSourceEnum.class})
public interface CarDealMapper {CarDealMapper INSTANCE = Mappers.getMapper(CarDealMapper.class);@Mappings({@Mapping(target = "demandSource", expression = "java(DemandSourceEnum.getMeaning(carDealDO.getDemandSource()))"),SaleDemandVO doToVo(CarDealDO carDealDO);
}
  • 自定义方法进行类型转换
@Mapper
public interface ItemConvert {ItemConvert INSTANCE = Mappers.getMapper(ItemConvert.class);SkuDTO2 domain2Dto(Sku2 sku2);default Item2 item1ToItem2(Item1 item1) {if (item1 == null) {return null;}Item2 item2 = new Item2();item2.setItemId(11111L);item2.setTitle(item1.getTitle());return item2;}
}// mapstruct 的实现类
@Generated(value = "org.mapstruct.ap.MappingProcessor",date = "2019-07-30T18:38:11+0800",comments = "version: 1.3.0.Final, compiler: javac, environment: Java 1.8.0_101 (Oracle Corporation)"
)
public class ItemConvertImpl implements ItemConvert {@Overridepublic SkuDTO2 domain2Dto(Sku2 sku2) {if ( sku2 == null ) {return null;}SkuDTO2 skuDTO2 = new SkuDTO2();skuDTO2.setSkuId( sku2.getSkuId() );skuDTO2.setSkuCode( sku2.getSkuCode() );if ( sku2.getSkuPrice() != null ) {skuDTO2.setSkuPrice( Long.parseLong( sku2.getSkuPrice() ) );}List<String> list = sku2.getNameList();if ( list != null ) {skuDTO2.setNameList( new ArrayList<String>( list ) );}// mapstruct直接调用的是在接口中自定义的实现skuDTO2.setItem( item1ToItem2( sku2.getItem() ) );return skuDTO2;}
}
  • 使用策略的方式进行类型转换
    若是类型在很多Mapper中都需要使用,比较使用下例
public class BooleanStrategy {public String booleanToString(Boolean value) {if (value == null) {return "--";}return value ? "是" : "否";}public Integer booleanToInteger(Boolean value) {if (value == null) {return null;}return value ? 1 : 0;}public Boolean IntegerToBoolean(Integer value) {if (value == null) {return null;}return value == 0 ? false : true;}public String dateFormate(Date date) {if (date == null) {return "--";}return DateFormatUtils.format(date, "yyyy-MM-dd HH:mm:ss");}
}@Mapper(uses = BooleanStrategy.class)
public interface CarDealMapper {CarDealMapper INSTANCE = Mappers.getMapper(CarDealMapper.class);CarDealDO dtoToDo(PlateCityMessageDTO plateCityMessageDTO);
}

方法中target和source 类型满足 BooleanStrategy方法的,会自动进行调用这个方法的类型转换进行处理

  • 自定义常量的方法

若是我们需要给一些属性定义一个固定的值,这个时候可以使用 constant

    @Mapping(target = "whetherPass", constant = "true")CentralizedNewCarShipDTO doToDubboDto(CarDealDO carDealDO);
  • 特殊类型的转换
  @Mapping(target = "createTime", dateFormat = "yyyy-MM-dd HH:mm:ss", expression = "java(new Date())")CarDTO doToDTO(CarDO carDO);

另外还有numberFormat定义数字的格式转换

  • 自定义初始值 defaultValue
    当source值为空的时候则会使用defaultValue定义的值。而constant则是无论source是否为空,都会使用constant定义的值,注意区分两者
   /*** 单个参数的直接使用** @param carDO source do* @return target dto*/@Mapping(target = "userName", constant = "yby")@Mapping(target = "modelColor", source = "modelColor", defaultValue = "标致")@Mapping(target = "createTime", dateFormat = "yyyy-MM-dd HH:mm:ss", expression = "java(new Date())")CarDTO doToDTO(CarDO carDO);

额外的请参考 org.mapstruct.Mapping

Collection转换

原理是遍历source collection然后转换类型,put到target collection中 如果是可以自动转换的则自动转换,同date type conversion;若是无法自动转换的,则会查看是否有可以调用的类型

@Mapper(imports = Date.class)
public interface CarMapper {CarMapper INSTANCE = Mappers.getMapper(CarMapper.class);/*** 基本类型collection的转换** @param integers* @return*/Set<String> integerSetToStringSet(Set<Integer> integers);/*** 调用存在已有方法的转换** @param cars* @return*/List<CarDTO> carsToCarDtos(List<CarDO> cars);/*** 单个参数的直接使用** @param carDO source do* @return target dto*/@Mapping(target = "userName", constant = "yby")@Mapping(target = "modelColor", source = "modelColor", defaultValue = "标致")@Mapping(target = "createTime", dateFormat = "yyyy-MM-dd HH:mm:ss", expression = "java(new Date())")CarDTO doToDTO(CarDO carDO);/*** DTO转为VO** @param warehouseValidDTOList* @return*/List<WarehouseValidPageVO> dtoToVo(List<WarehouseValidDTO> warehouseValidDTOList);
}// mapstruct实现@Generated(value = "org.mapstruct.ap.MappingProcessor",date = "2019-07-30T19:27:05+0800",comments = "version: 1.3.0.Final, compiler: javac, environment: Java 1.8.0_101 (Oracle Corporation)"
)
public class CarMapperImpl implements CarMapper {@Overridepublic Set<String> integerSetToStringSet(Set<Integer> integers) {if ( integers == null ) {return null;}Set<String> set = new HashSet<String>( Math.max( (int) ( integers.size() / .75f ) + 1, 16 ) );for ( Integer integer : integers ) {set.add( String.valueOf( integer ) );}return set;}@Overridepublic List<CarDTO> carsToCarDtos(List<CarDO> cars) {if ( cars == null ) {return null;}List<CarDTO> list = new ArrayList<CarDTO>( cars.size() );for ( CarDO carDO : cars ) {list.add( doToDTO( carDO ) );}return list;}@Overridepublic CarDTO doToDTO(CarDO carDO) {if ( carDO == null ) {return null;}CarDTO carDTO = new CarDTO();if ( carDO.getModelColor() != null ) {carDTO.setModelColor( carDO.getModelColor() );}else {carDTO.setModelColor( "标致" );}if ( carDO.getNewCarGuidePrice() != null ) {carDTO.setNewCarGuidePrice( BigDecimal.valueOf( carDO.getNewCarGuidePrice() ) );}carDTO.setBrandCode( carDO.getBrandCode() );carDTO.setBrandName( carDO.getBrandName() );carDTO.setSeriesCode( carDO.getSeriesCode() );carDTO.setSeriesName( carDO.getSeriesName() );carDTO.setModelCode( carDO.getModelCode() );carDTO.setModelName( carDO.getModelName() );carDTO.setModelColorCode( carDO.getModelColorCode() );carDTO.setUserName( "yby" );carDTO.setCreateTime( new Date() );return carDTO;}
@Overridepublic List<WarehouseValidPageVO> dtoToVo(List<WarehouseValidDTO> warehouseValidDTOList) {if ( warehouseValidDTOList == null ) {return null;}List<WarehouseValidPageVO> list = new ArrayList<WarehouseValidPageVO>( warehouseValidDTOList.size() );for ( WarehouseValidDTO warehouseValidDTO : warehouseValidDTOList ) {list.add( warehouseValidDTOToWarehouseValidPageVO( warehouseValidDTO ) );}return list;}protected WarehouseValidPageVO warehouseValidDTOToWarehouseValidPageVO(WarehouseValidDTO warehouseValidDTO) {if ( warehouseValidDTO == null ) {return null;}WarehouseValidPageVO warehouseValidPageVO = new WarehouseValidPageVO();warehouseValidPageVO.setId( warehouseValidDTO.getId() );warehouseValidPageVO.setWarehouseNo( warehouseValidDTO.getWarehouseNo() );warehouseValidPageVO.setWarehouseName( warehouseValidDTO.getWarehouseName() );warehouseValidPageVO.setPlateValid( warehouseValidDTO.getPlateValid() );return warehouseValidPageVO;}
}
map
public interface SourceTargetMapper {@MapMapping(valueDateFormat = "dd.MM.yyyy")Map<String, String> longDateMapToStringStringMap(Map<Long, Date> source);
}// mapstruct自己实现
@Generated(value = "org.mapstruct.ap.MappingProcessor",date = "2019-07-30T19:35:22+0800",comments = "version: 1.3.0.Final, compiler: javac, environment: Java 1.8.0_101 (Oracle Corporation)"
)
public class SourceTargetMapperImpl implements SourceTargetMapper {@Overridepublic Map<String, String> longDateMapToStringStringMap(Map<Long, Date> source) {if ( source == null ) {return null;}Map<String, String> map = new HashMap<String, String>( Math.max( (int) ( source.size() / .75f ) + 1, 16 ) );for ( java.util.Map.Entry<Long, Date> entry : source.entrySet() ) {String key = new DecimalFormat( "" ).format( entry.getKey() );String value = new SimpleDateFormat( "dd.MM.yyyy" ).format( entry.getValue() );map.put( key, value );}return map;}
}

mapstruct 之 类型转换相关推荐

  1. Java VO转PO(MapStruct使用)

    文章目录 一.代码分层介绍 1.应用分层与领域模型 2.为什么要应用分层开发和区分领域模型 3.不同的实体类间进行转换 二.使用MapStruct 1.官方文档Introduction翻译 2.添加M ...

  2. MapStruct系列(5)-映射器数据类型转换详解

    文章目录 前言 1. 隐式类型转换 2. 映射引用类型 3. 嵌套映射 4. 调用自定义映射方法 5. 调用其他映射器 6. 将映射目标类型传递给自定义映射器 7. 将上下文或状态对象传递给自定义方法 ...

  3. 类型转换神器Mapstruct新出的Spring插件真好用

    胖哥在几年前安利过Mapstruct这个神器,它可以代替BeanUtil来进行DTO.VO.PO之间的转换.它使用的是Java编译期的  annotation processor 机制,说白了它就是一 ...

  4. 还在用 BeanUtils来做对象转换吗?快试试 MapStruct吧

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 作者:阿进的写字台 https://www.cnblogs ...

  5. 丢弃掉那些BeanUtils工具类吧,MapStruct真香!!!

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 在前几天的文章<为什么阿里巴巴禁止使用Apache Bean ...

  6. java map 结构体_业务代码的救星——Java 对象转换框架 MapStruct 妙用

    简介 在业务项目的开发中,我们经常需要将 Java 对象进行转换,比如从将外部微服务得到的对象转换为本域的业务对象 domain object,将 domain object 转为数据持久层的 dat ...

  7. string转换bigdecimal_使用MapStruct处理恼人的bean转换

    烦人的Bean 转换 对于代码中 JavaBean之间的转换, 一直是困扰我很久的事情.在开发的时候我看到业务代码之间有很多的 JavaBean 之间的相互转化, 非常的影响观感, 却又不得不存在.我 ...

  8. 定义一个dto对象_业务代码的救星——Java 对象转换框架 MapStruct 妙用

    在业务项目的开发中,我们经常需要将 Java 对象进行转换,比如从将外部微服务得到的对象转换为本域的业务对象 domainobject,将 domainobject 转为数据持久层的 dataobje ...

  9. Java对象转换方案分析与mapstruct实践

    简介: 随着系统模块分层不断细化,在Java日常开发中不可避免地涉及到各种对象的转换,如:DO.DTO.VO等等,编写映射转换代码是一个繁琐重复且还易错的工作,一个好的工具辅助,减轻了工作量.提升开发 ...

最新文章

  1. AI又被彩虹吹!​网易被预言为“下一个百度”?
  2. 加密(Asp.Net配置文件的)配置节
  3. python地图 两点距离_没学过还真不会!怎样才能画出准确的地图?
  4. using IDisposable
  5. 突发!Python再次第一,Java和C下降,凭什么? ​
  6. A2K课程目录及学习计划
  7. [笔记]kubernetes 无法启动问题
  8. 树莓派Python 3.x+TensorFlow 1.9.0
  9. javascript第二天学习
  10. 数学建模安装matlab,数学建模神器——Matlab下载安装教程
  11. 重装ubuntu16.04之搜狗拼音输入法
  12. FusionAccess桌面云
  13. GitHub标星90K,这份持续霸榜的Leetcode刷题手册到底有多强?
  14. python学什么书_python自学用什么书
  15. Android ListView 异步加载图片
  16. 如何评价一个好系统?
  17. [OHIF-Viewers]医疗数字阅片-医学影像-中间插播一下-es6-使用const加箭头函数声明函数相对于function声明函数有什么好处?...
  18. 这可能是最完整的进藏攻略
  19. QT中读取STL并显示
  20. mySQL 事物提交成功不等于数据保存成功

热门文章

  1. readOGR加载shape文件时报错
  2. 基于数字认证的零信任安全架构在医疗领域的应用
  3. TinyXML2使用方法及示例
  4. sql2008 新建登录用户只能修改某一个表 服务器角色,sql语句创建新登录名和设置权限...
  5. 电脑便签怎么嵌入桌面使其不可移动呢?
  6. 云计算的基本概念(转载)
  7. leaflet+geoserve+jquery实现简单Webgis系统(附源码下载)
  8. 微软编程一小时比赛--题目1 : Arithmetic Expression
  9. 火车头插件:文章自动配相关图片(文章插入相关图片|文章自动配图)
  10. python库——图形艺术