下面是我的映射器界面。我正在使用mapstruct 1.3.0.Final
。
@Mapper(componentModel = "spring")
public interface ApiMapper {
@Mappings({
@Mapping(source = "in.entityName.fn", target="name.fn"),
@Mapping(source = "in.entityName.ln", target="name.ln"),
@Mapping(source = "in.salute.sln", target="name.salutation"),
})
public MyOutput map(InputData in);
}
看起来超级简单,但是实现类在目标中两次设置了name
对象,所以我只得到了最后一个映射对象。有人可以帮助我了解我在这里想念什么或做错什么吗?
@Component
public class ApiMapperImpl implements ApiMapper {
@Override
public MyOutput map(InputData in) {
if ( in == null ) {
return null;
}
MyOutput myOutput = new MyOutput();
myOutput.setName( entityNameToNameDetails( in.getEntityName() ) );
myOutput.setName( saluteServiceOutputToNameDetails( in.getSalute() ) );
return myOutput;
}
protected NameDetails entityNameToNameDetails(EntityName entityName) {
if ( entityName == null ) {
return null;
}
NameDetails nameDetails = new NameDetails();
nameDetails.setFn( entityName.getFn() );
nameDetails.setLn( entityName.getLn() );
return nameDetails;
}
protected NameDetails saluteServiceOutputToNameDetails(SaluteServiceOutput saluteServiceOutput) {
if ( saluteServiceOutput == null ) {
return null;
}
NameDetails nameDetails = new NameDetails();
nameDetails.setSalutation( saluteServiceOutput.getSln() );
return nameDetails;
}
}
我认为,您应该在这种情况下帮助mapstruct,添加一个简单的方法,例如:
@Mappings({
@Mapping(source = "in.entityName.fn", target="fn"),
@Mapping(source = "in.entityName.ln", target="ln"),
@Mapping(source = "in.salute.sln", target="salutation"),
})
public NameDetails mapNameDetails(InputData in);`
我从here和here找到了答案。我喜欢第二个选项来使用@MappingTarget
更新现有的bean。唯一的新变化是,我需要为MyOutput
创建对象并在调用map方法时使用它。
我已经修改了我的映射器代码,如下所示:
@Mappings({
@Mapping(source = "in.entityName.fn", target="out.name.fn"),
@Mapping(source = "in.entityName.ln", target="out.name.ln"),
@Mapping(source = "in.salute.sln", target="out.name.salutation"),
})
public void mapNameDetails(InputData in, @MappingTarget MyOutput out);
以上映射器代码的Junit
。
@Autowired
private ApiMapper apiMapper;
@Test
public void testApiMapper() {
MyOutput output = new MyOutput();
InputData input = createInputData();
apiMapper.mapNameDetails(input, output);
assertNotNull(output);
assertNotNull(output.getName());
assertEquals("Sridhar", output.getName().getFn());
assertNull(output.getName().getLn());
assertEquals("Mr.", output.getName().getSalutation());
}
private InputData createInputData() {
InputData data = new InputData();
data.setEntityName(new EntityName());
data.setSalute(new SaluteServiceOutput());
data.getEntityName().setFn("Sridhar");
data.getSalute().setSln("Mr.");
return data;
}