2017-09-06 139 views
1

我有要求将源类中的字段值映射到字段属性的位置。我能够使用Mapstruct使用@Mapper注释的 '表达' 参数做MAPtruct - 将字段值映射到属性

源类:

public class ClassA { 

    public ClassA() { 
    } 

    private String name; 
    private String address; 

    private ArrayList<RequestFilter> filter; 

    public ArrayList<RequestFilter> getFilter() { 
     return filter; 
    } 

    public void setFilter(ArrayList<RequestFilter> filter) { 
     this.filter = filter; 
    } 

    public String getName() { 
     return name; 
    } 

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

    public String getAddress() { 
     return address; 
    } 

    public void setAddress(String address) { 
     this.address = address; 
    } 

} 

目标类:

public class ClassATransform { 

    public ClassATransform() { 
    } 

    private String name; 
    private String id; 
    private String address; 
    public String getName() { 
     return name; 
    } 
    public void setName(String name) { 
     this.name = name; 
    } 
    public String getAddress() { 
     return address; 
    } 
    public void setAddress(String address) { 
     this.address = address; 
    } 
    public String getId() { 
     return id; 
    } 
    public void setId(String id) { 
     this.id = id; 
    } 
} 

我mapstruct映射器看起来是这样的:

@Mapper(imports=RequestFilter.class) 
public interface ClassAMapper { 

    ClassAMapper INSTANCE = Mappers.getMapper(ClassAMapper.class); 

    @Mappings({ 
     @Mapping(target = "name", source = "name"), 
     @Mapping(target= "address", source = "address"), 
     @Mapping(target = "id", expression="java(req.getFilter().get(req.getFilter().indexOf(new RequestFilter(\"id\"))).filterValue)") 
    }) 
    ClassATransform classAToDTO(ClassA req); 
} 

RequestFilter.java:

public class RequestFilter { 

public RequestFilter() { 
} 


public RequestFilter(String filterName) { 
    this.filterName = filterName; 
} 


public String filterName; 
public String filterValue; 
public String filterOperator; 
public String joinOperator; 
@Override 
public int hashCode() { 
    final int prime = 31; 
    int result = 1; 
    result = prime * result + ((filterName == null) ? 0 : filterName.hashCode()); 
    return result; 
} 
@Override 
public boolean equals(Object obj) { 
    if (this == obj) 
     return true; 
    if (obj == null) 
     return false; 
    if (getClass() != obj.getClass()) 
     return false; 
    RequestFilter other = (RequestFilter) obj; 
    if (filterName == null) { 
     if (other.filterName != null) 
      return false; 
    } else if (!filterName.equals(other.filterName)) 
     return false; 
    return true; 
    } 
} 

有没有其他方法可以在不使用“表达式”的情况下进行映射?

回答

1

你可以提供一个自定义的方法,将其映射为您:

@Mapper 
public interface ClassAMapper { 

    ClassAMapper INSTANCE = Mappers.getMapper(ClassAMapper.class); 

    @Mappings({ 
     @Mapping(target = "id", source = "req") 
    }) 
    ClassATransform classAToDTO(ClassA req); 

    default String mapToid(ClassA req) { 
     // null checks 
     return reg.getFilter() 
        .stream() 
        .filter(filter -> filter.filterName.equals("id")) 
        .findAny() 
        .orElse(null); 
    } 
} 

顺便说一句。 和target相同的映射不需要,因为MapStruct会自动执行该操作。

+0

感谢您的回答。那么如果在数组中有'n'RequestFilter,我需要'n''default'方法吗? – ssdimmanuel

+0

如果你有'n'RequestFilters,我建议你使用'@ AfterMapping',你可以在那里传入源和目标并在那里做映射。这对性能会更好,并且您不需要使用限定符来定义n'@ Mapping'就可以使其工作 – Filip