MapStruct:将数据从一个bean传输到另一个bean

将数据从一种形式转换为另一种形式在IT行业中是一种被高度利用的概念。 MapStruct通过在编译时生成映射器实现,允许基于注释的Bean转换。 这样可以确保在运行时没有性能开销。

什么是MapStruct?

MapStruct是一个代码生成器,它基于约定优于配置的方法大大简化了Java Bean类型之间的映射的实现。

生成的映射代码使用简单的方法调用,因此速度快,类型安全且易于理解。

为什么选择MapStruct?

多层应用程序通常需要在不同的对象模型(例如实体和DTO)之间进行映射。 编写此类映射代码是一项繁琐且容易出错的任务。 MapStruct旨在通过使其尽可能自动化来简化这项工作。

与其他映射框架相比,MapStruct在编译时生成Bean映射,以确保高性能,允许快速的开发人员反馈和彻底的错误检查。

实作

pom.xml

在web.xml中,添加“ maven-compiler-plugin ”,并使用组ID“ org.apache.maven.plugins ”。 您可以添加特定的jdk源/目标版本,并从以下位置获取最新版本
MapStruct网站 。


 org.apache.maven.plugins
 maven-compiler-plugin
 3.5.1
 
  1.6 
  1.6 
  
   
    org.mapstruct
    mapstruct-processor
    1.1.0.Beta1
   
  
 

现在添加mapstruct jar作为依赖项。


 org.mapstruct
 mapstruct
 1.1.0.Beta1

问题陈述与解决方案

假设我们有两个表示个人和业务联系的pojo,如下所述,并且我们都在特定的jsps上使用这两个pojo。 现在,对于两个联系人都相同的功能,我们需要将数据从一种pojo传输到另一种。

PrimaryContact.java

public class PrimaryContact {

 private String name;
 private String phone;
 private String email;

 public PrimaryContact() {
  super();
 }

 public PrimaryContact(String name, String phone, String email) {
  super();
  this.name = name;
  this.phone = phone;
  this.email = email;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public String getPhone() {
  return phone;
 }

 public void setPhone(String phone) {
  this.phone = phone;
 }

 public String getEmail() {
  return email;
 }

 public void setEmail(String email) {
  this.email = email;
 }

 @Override
 public String toString() {
  return "PrimaryContact [name=" + name + ", phone=" + phone + ", email=" + email + "]";
 }

}

BusinessContact.java

public class BusinessContact {

 private String firstName;
 private String lastName;
 private String businessPhone;
 private String businessEmail;
 private String businessCountry;

 public BusinessContact() {
  super();
 }

 public BusinessContact(String firstName, String lastName, String businessPhone, String businessEmail,
   String businessCountry) {
  super();
  this.firstName = firstName;
  this.lastName = lastName;
  this.businessPhone = businessPhone;
  this.businessEmail = businessEmail;
  this.businessCountry = businessCountry;
 }

 public String getFirstName() {
  return firstName;
 }

 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }

 public String getLastName() {
  return lastName;
 }

 public void setLastName(String lastName) {
  this.lastName = lastName;
 }

 public String getBusinessPhone() {
  return businessPhone;
 }

 public void setBusinessPhone(String businessPhone) {
  this.businessPhone = businessPhone;
 }

 public String getBusinessEmail() {
  return businessEmail;
 }

 public void setBusinessEmail(String businessEmail) {
  this.businessEmail = businessEmail;
 }

 public String getBusinessCountry() {
  return businessCountry;
 }

 public void setBusinessCountry(String businessCountry) {
  this.businessCountry = businessCountry;
 }

 @Override
 public String toString() {
  return "BusinessContact [firstName=" + firstName + ", lastName=" + lastName + ", businessPhone=" + businessPhone
    + ", businessEmail=" + businessEmail + ", businessCountry=" + businessCountry + "]";
 }

}

我们编写一个Mapper来传输数据,如下所示。 注释@Mappings定义了将源pojo中的哪些属性转移到目标pojo中的特定属性。 批注定义@InheritInverseConfiguration反向映射要完成。

ContactMapper.java

/**
 * @author javareferencegv
 */
@Mapper
@DecoratedWith(ContactMapperDecorator.class)
public interface ContactMapper {
 ContactMapper INSTANCE = Mappers.getMapper(ContactMapper.class);
    
 /**
  * We define only those mappings which doesn't have same signature in source and target
  */   
    @Mappings({ 
     @Mapping(source = "phone", target = "businessPhone"),
     @Mapping(source = "email", target = "businessEmail"),
     @Mapping(target = "businessCountry", constant="USA")
    })
    BusinessContact primaryToBusinessContact(PrimaryContact primary);
    @InheritInverseConfiguration
    PrimaryContact businessToPrimaryContact(BusinessContact business);
   
}

在某些情况下,映射不是直接的,我们需要在将一个属性映射到另一个属性之前使用自定义逻辑。 这里的一个例子是主要联系人有全名,而业务联系人有名和姓。 在这种情况下,我们使用装饰器添加自定义实现。 这是在映射器中添加定义的注释@DecoratedWith。 装饰器的实现如下:

ContactMapperDecorator.java

public abstract class ContactMapperDecorator implements ContactMapper{
 
 private final ContactMapper delegate;
  
    public ContactMapperDecorator(ContactMapper delegate) {
        this.delegate = delegate;
    }
    
    @Override
    public BusinessContact primaryToBusinessContact(PrimaryContact primary){
     BusinessContact business = delegate.primaryToBusinessContact(primary); //Executes the mapper
     String[] names = primary.getName().split(" ");
     business.setFirstName(names[0]);
     business.setLastName(names[1]);
     return business;
    }
    
    @Override
    public PrimaryContact businessToPrimaryContact(BusinessContact business){
     PrimaryContact primary = delegate.businessToPrimaryContact(business); //Executes the mapper
     primary.setName(business.getFirstName() + " " + business.getLastName());
     return primary;
    }
    
}

执行方式:

一旦我们构建了一个实现类文件,它将由mapstruct生成。 我们都准备运行映射器。

public class ContactConvertor {

 public static void main(String[] args) {
  PrimaryContact primary = new PrimaryContact("Jack Sparrow","9999999999","[email protected]");
  BusinessContact business = ContactMapper.INSTANCE.primaryToBusinessContact(primary);
  System.out.println(business);
  PrimaryContact primaryConverted = ContactMapper.INSTANCE.businessToPrimaryContact(business);
  System.out.println(primaryConverted);
 }

}

输出:

BusinessContact [firstName=Jack, lastName=Sparrow, businessPhone=9999999999, [email protected], businessCountry=USA]
PrimaryContact [name=Jack Sparrow, phone=9999999999, [email protected]]

翻译自: https://www.javacodegeeks.com/2016/12/mapstruct-transferring-data-one-bean-another.html

你可能感兴趣的:(MapStruct:将数据从一个bean传输到另一个bean)