数据实体转换MapStruct常用点

简介: MapStruct

在代码开发过程中,大型系统进行微服务化拆分,各个核心模块也会进行必要的业务代码分层,层与层之间参数传导过程中,各参数实体对像的属性传递等也变得越来越重要,这个过程中,大量的套路式代码get/set等也会出现在属性传递过程中,mapstruct即为解决这部分套路式代码提供了良好的解决方案,实际使用过程中,定议基于target/source的接口,同时添加不同属性名的映射,即可在编译过程中自动生成对应的实现,极大的简化了操作

 

MAVEN依赖

<dependency>
   <
groupId>org.mapstruct</groupId>
   <
artifactId>mapstruct-jdk8</artifactId>
   <
version>1.2.0.Final</version>
</
dependency>

<
dependency>
   <
groupId>org.mapstruct</groupId>
   <
artifactId>mapstruct-processor</artifactId>
   <
version>1.2.0.Final</version>
</
dependency>

 

 

测试Demo

测试目录结构


 

基本对像

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class School {
    private String schoolName; 
    private Student st;
} 
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
  public class Student {
    private String name; 
    private int age;
  }
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
  public class SchoolDO {
    private String schoolName;
    private StudentDO stNew;
  }
 
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
  public class StudentDO {
    private String name;
    private int newAge;
  }

 

 

通用方式-1

使用基础的泛型接口,实际接口直接继承泛型接口使用

l  字段属性名一致情况下无需再额外定义转换函数

l  如有字段属性名不一致,仅需重载单条记录的转换函数,同时添加map映射source/target的属性名

l  Eg: StudentConvert, 仅一个简单接口即实现了数据的转换,属性名也作了映射

public interface BasicMapper<SOURCE, TARGET> {
    /**
     * @Mappings({
     * @Mapping(source = "code", target = "newCode"),
     * @Mapping(source = "name", target = "newName")
     * })
     */
    @Mappings({})
    @InheritConfiguration
    TARGET to(SOURCE source);  

    @InheritConfiguration
    List<TARGET> to(Collection<SOURCE> source);  
   
@InheritInverseConfiguration     SOURCE from(TARGET source);
   
@InheritInverseConfiguration     List<SOURCE> from(Collection<TARGET> source); }
 
@Component
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface StudentConvert extends BasicMapper<Student, StudentDO>{
    
@Mappings({      @Mapping(source = "age", target = "newAge")      })      StudentDO to(Student source); } 
public static void main(String[] args) {
    SpringApplication.run(StructTest.class, args);
    ApplicationContext context = SpringUtil.getApplicationContext();
    StudentConvert stConvert = context.getBean(StudentConvert.class);
    /**
 * 实际转换中直接可单条或是多条list记录,并且有属性名不一致也可以
 * mapper接口中指定
 */
    Student st = Student.builder().name("student").age(18).build();
    Student st2 = Student.builder().name("student2").age(180).build();
    List<Student> stList = Lists.newArrayList(st, st2); 
    List<StudentDO> stDos = stConvert.to(stList);
    System.out.println(stDos.toString());
}
 

 


 

 

通用方式-2

嵌套转换

l  对像本身要作属性的映射转换

l  对像内某些属性也需作属生的映射转换

定议外层的映射接口,在接口中直接指定该属性对像的转换类,如下School对像中的student属性也要作相应的属性转换,可接口中直接指定 uses = {StudentConvert.class}:

@Component
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE, uses = {StudentConvert.class})
public interface SchoolConvert {      @Mappings({          @Mapping(source = "st", target = "stNew")      })      SchoolDO to(School source); }
 
@SpringBootApplication
  public class StructTest { 
   
public static void main(String[] args) {         SpringApplication.run(StructTest.class, args);         ApplicationContext context = SpringUtil.getApplicationContext();    
       
//demo 2         SchoolConvert schoolConvert = context.getBean(SchoolConvert.class);
       
School school = School.builder().schoolName("school-1").st(st).build();
       
SchoolDO schDO = schoolConvert.to(school);
       
System.out.println(schDO);
   
}
}
 

 

 

 

 

通用方式-3

l  Source对像中的属性对像中的属性转target属性

l  target对像中的属性对像中的属性转source属性

l  表达式取值(枚举类/常量)

l  调用自定义函数取值映射

 

@Mappings(
        @Mapping(source = "orderItem.discountInfo", target = "discountInfo")
)
ItemDetailDto order2itemdetail(OrderBaseDto orderBaseDto);
 @Mappings({
       
@Mapping(target = "materialId",source = "giftDetail.materialId")})
DemoDto command2ToDto(DemoCommand demoCommand);
 
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE,
imports = {TypeEnum.class})
public interface CampaignInputConvert {
  
    @Mappings({         
           
@Mapping(target ="giftType",expression = "java(TypeEnum.ITEM_NO.code()"),                     
           
@Mapping(target = "media",expression = "java(CommonConsts.SEND_MEDIA)")         
    })
   
GiftDemoBaseDto goodsDetailToGiftRpc(GoodsDemoOutput goodsDemoOutput, CustDemoOutput custDemoOutput, CustDemoDO custDemoDO);
 
@Component
@Mapper
(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface DemoInfoConvert {
   
List<DemoInfo> discntInfoDtoList2DemoInfoList(List<DemoInfoDto> demoInfoDtos);
   
@Mappings({
      
@Mapping(target = "discountValue", expression = "java(getDemotValue(discntInfoDto))")
    })
   
CouponInfo dto2output(DiscntInfoDto discntInfoDto);
    default
Long getDemoValue(DemoInfoDto demoInfoDto) {
       
if (discntInfoDto.getDiscountValue() != null) {
           
return discntInfoDto.getDiscountValue();
       
} else {
           
return discntInfoDto.getReduceValue();
       
}
    }
}

 

 

相关文章
|
数据建模 Linux 数据库
简单实用的数据建模工具PDManer
PDManer是一款开源的国产数据建模工具
14909 1
简单实用的数据建模工具PDManer
|
fastjson 前端开发
巧用fastjson自定义序列化类实现字段的转换
项目中突然需要增加另一个字段的查找,而这个查找需要查另一张表的记录。 但现在产品很多地方都要增加该字段,如何最快的实现该功能呢。 办法如下: 通过fastjson序列化时,增加该字段的序列化类,该序列化类通过CODE查找名称,并序列化到前端。
6314 0
|
SQL 存储 缓存
Mybatis的一级缓存,二级缓存过期时间分析
Mybatis的一级缓存,二级缓存过期时间分析
1143 0
|
6月前
|
缓存 Windows
彻底卸载软件且不留痕!卸载+清理+启动项优化,彻底清理残留信息
一款小巧高效的卸载工具,仅3.85M,主打彻底清理软件残留文件、注册表、服务等。支持强制卸载、应用商店程序移除、浏览器扩展管理、注册表清理、垃圾文件扫描及空文件夹清理,并提供文件粉碎、快捷方式修复等功能,界面简洁且可换肤,是系统清理的得力助手。
524 6
|
XML Java 数据库连接
解决org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)问题
解决org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)问题
15070 2
解决org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)问题
|
Web App开发 存储 JavaScript
深入浅出Node.js后端开发
【10月更文挑战第31天】本文将引导你进入Node.js的奇妙世界,探索其如何革新后端开发。通过浅显易懂的语言和实际代码示例,我们将一起学习Node.js的核心概念、搭建开发环境,以及实现一个简单但完整的Web应用。无论你是编程新手还是希望拓展技术的开发者,这篇文章都将为你打开一扇通往高效后端开发的大门。
|
存储 Java 测试技术
阿里巴巴java开发手册
这篇文章是关于阿里巴巴Java开发手册的整理,内容包括编程规约、异常日志、单元测试、安全规约、MySQL数据库使用以及工程结构等方面的详细规范和建议,旨在帮助开发者编写更加规范、高效和安全的代码。
|
机器学习/深度学习 人工智能 算法
2024年,计算机相关专业还值得选择吗?
2024年,计算机相关专业还值得选择吗?
|
安全 Java Maven
零配置,零麻烦:MapStruct 的轻松对象映射之旅
零配置,零麻烦:MapStruct 的轻松对象映射之旅
962 0