MapStruct解绑DTO与DO的映射赋值

MapStruct是一个类型安全的映射处理工具,能把已定义的类,映射到另一个类。解耦了对象之间的依赖关系。

一、问题场景再现

一般我们写业务时,都要处理DTO与DO的转换。假设要添加一个Man数据,将客户端传入的DTO转成DO,笨拙的做法是new一个DO将Man所有的属性赋值一遍,然后再用MyBatis的DAO插入到数据库。如下代码所示:

public class Man {//Man 
   private String name;
   private String age;
   private String mobileNO;
}
public class InsertRequst{//Man DTO
   private String name;
   private String age;
   private String mobileNO;
   private String serialNO;
   private String SMSCode;
   ...//get set 方法省略
}
@RestController
public String insertMan(@RequestBody InsertRequst insertRequst)//客户端传入请求
{
   if(!checkSMS(insertRequst.getSMSCode())){
      return "验证码错误";
   }
   Man man=new Man(){//此处为DTO到DO的转换,其他地方需要处理Man实体,就会出现多处类似代码
      name=insertRequst.name;
      age=insertRequst.age;
      mobileNO=insertRequst.mobileNO;
  }   
  ManMapper.insert(man);
  ...//其余代码省略
}

二、MapStruct主角上场

Spring boot下的MapStruct,可以对这两个实体进行映射,需要定义一个映射器提供映射服务,这个映射器对应如下代码的ManMapper

@RestController
public String insertMan(@RequestBody InsertRequst insertRequst)
{
   if(!checkSMS(insertRequst.getSMSCode())){
      return "验证码错误";
   }
   Man man=ManMapper.INSTANCE.toMan(InsertRequst.class);
   Mapper.insert(man);
  ...//其余代码省略
}

映射处理器(ManMapper 接口)

@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE)//这里要写上,忽略不匹配的属性
public interface ManMapper {
    ManMapper INSTANCE = Mappers.getMapper( ManMapper.class );
    Man toMan(InsertRequst man);
    //还可以进行映射定义,假设Man的name字段是manName,如
    //@Mapping(source="name",target="manName")
    //Man toMan(InsertRequst man);
}

三、小结

最后引用MapStruct官网上的一段话,概括一下MapStruct的特点:

Compared to dynamic mapping frameworks, MapStruct offers the following advantages:
相比于上文的动态映射框架,MapStruct有如下几点优势:
Fast execution by using plain method invocations instead of reflection
使用普通的方法调用快效执行而不是编写反射
Compile-time type safety: Only objects and attributes mapping to each other can be mapped, no accidental mapping of an order entity into a customer DTO etc.
编译时类型安全:只有匹配成功的对象属性才会被成功映射,不会出现订单型实体映射到DTO
Clear error-reports at build time, if
有如下情况,运行期间会清晰报错:
. mappings are incomplete (not all target properties are mapped)
映射未全(不是所有的目标属性都能被映射到)
. mappings are incorrect (cannot find a proper mapping method or type conversion)
映射错误(找不到匹配的映射方法或类型)

上一篇:恕我直言,在座的各位根本写不好Java!


下一篇:使用Kotlin Data类替换Java DTO类的问题