假设我有两个dto,我希望用MapStruct对它们进行映射,DTO1和DTO2具有基本相同的字段,只是命名不同,我希望将它们从一个映射到另一个。使用MapStruct,我可以这样做:
@Mapping(target = "desiredName", source = "notDesiredName")
// etc
DTO1 toDto1(Dto2 dto2);
但是假设我在Dto2中只有一个属性,我想首先通过一个函数传递。我知道我可以:
default DTO1 toDto1(Dto2 dto2) {
...
dto1.setSomething(myFunction(dto.getSomething)
...
}
如何避免必须重新定义每个其他属性转换?
默认情况下,Mapstruct将自动传输所有具有相同名称/类型的字段。为了干预自动完成的操作,请使用@AfterMapping
注释和代码,只使用例外。(或使用@BeforeMapping
)
import org.mapstruct.AfterMapping;
import org.mapstruct.Mapper;
import org.mapstruct.MappingTarget;
import com.example.demo.dto.Dto1;
import com.example.demo.dto.Dto2;
@Mapper
public abstract class DtoMapper {
@Mapping(target = "desiredName", source = "notDesiredName")
@AfterMapping
protected void interveneWithSomethingThatChanges (Dto1 dto1, @MappingTarget Dto2 dto2) {
dto2.somethingThatChanges = dto1.somethingThatChanges + ": changed";
}
public abstract Dto2 toDto2(Dto1 dto1);
}
剩余代码如下:
MapperMain.java
import org.mapstruct.factory.Mappers;
import com.example.demo.dto.Dto1;
import com.example.demo.dto.Dto2;
import com.example.demo.mapper.DtoMapper;
public class MapperMain {
public static void main(String[] args) {
final DtoMapper mapper
= Mappers.getMapper(DtoMapper.class);
Dto1 dto1 = new Dto1("somethingThatChanges", "somethingThatStaysTheSame", "somethingElseThatStaysTheSame");
Dto2 dto2 = mapper.toDto2(dto1);
System.out.println(dto2);
}
}
输出:
Dto2 [somethingThatChanges=somethingThatChanges: changed, somethingThatStaysTheSame=somethingThatStaysTheSame, desiredName=somethingElseThatStaysTheSame]
Dto1.java
public class Dto1 {
public String somethingThatChanges;
public String somethingThatStaysTheSame;
public String notDesiredName;
public Dto1(String somethingThatChanges, String somethingThatStaysTheSame, String notDesiredName) {
this.somethingThatChanges = somethingThatChanges;
this.somethingThatStaysTheSame = somethingThatStaysTheSame;
this.notDesiredName = notDesiredName;
}
}
Dto2.java
public class Dto2 {
@Override
public String toString() {
return "Dto2 [somethingThatChanges=" + somethingThatChanges + ", somethingThatStaysTheSame="
+ somethingThatStaysTheSame + ", desiredName=" + desiredName + "]";
}
public String somethingThatChanges;
public String somethingThatStaysTheSame;
public String desiredName;
}
如果你有一个自定义函数来映射一个特定的属性,你可以使用限定符。
。
@Mapper
public interface MyMapper {
@Mapping(target = "something", qualifiedByName = "customSomething")
DTO1 toDto1(Dto2 dto2);
@Named("customSomething")
default String mapSomething(String value) {
// perform mapping
}
}
让我们来消化一下这个例子。在本例中,DTO1
和DTO2
都有一个名为something
的字段。因此,我们只需要定义Mapping#target
(当目标和源匹配时,Mapping#source
就过时了)。
下一个事实是,我们想执行一些特殊的方式来映射这个字段。我们用Mapping#qualifiedByName
来定义它。这告诉MapStruct查找带有@Named("customSomething")
注释的自定义映射方法。
mapSomething
方法是一个带有@Named("customSomething")
注释的自定义方法,这告诉MapStruct这是一个特殊的映射方法,它应该只在用户特别请求(使用Mapping#qualifiedBy
)时使用