Java MapStruct:嵌套的Iterable到Non-Iterable映射?
我发现了这个关于使用限定符从Iterable到Non-Iterable映射的示例: 但是如何使此映射能够映射嵌套属性(使用点注释) 例如,将源对象中集合的第一个元素的字段xyz映射到目标对象上的普通字段 该示例定义了一个限定符Java MapStruct:嵌套的Iterable到Non-Iterable映射?,java,mapstruct,Java,Mapstruct,我发现了这个关于使用限定符从Iterable到Non-Iterable映射的示例: 但是如何使此映射能够映射嵌套属性(使用点注释) 例如,将源对象中集合的第一个元素的字段xyz映射到目标对象上的普通字段 该示例定义了一个限定符 @Qualifier @Target(ElementType.METHOD) @Retention(RetentionPolicy.SOURCE) public @interface FirstElement { } 然后定义一个自定义映射器 public
@Qualifier
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface FirstElement {
}
然后定义一个自定义映射器
public class MapperUtils {
@FirstElement
public <T> T first(List<T> in) {
if (in != null && !in.isEmpty()) {
return in.get(0);
}
else {
return null;
}
}
}
但是,如果我想从电子邮件集合的第一个元素中提取一个特定字段,例如,像我对codeemails所做的那样。get(0)。getEmailAddress
例如,我希望编写如下映射:
@Mapping(target = "emailaddress", source = "emails[0].emailAddress")
您只需更改
MapperUtils
public class MapperUtils {
@FirstElement
public String firstEmailAddress(List<Person> in) {
if (in != null && !in.isEmpty()) {
return in.get(0).getEmailAddress();
}
else {
return null;
}
}
}
但是,如果您犯了错误,使用表达式可能会导致编译时问题。MapStruct不检查表达式的有效性,而是按原样使用它。另一个选项是在映射器中使用下面的行 这将使用helperclass来帮助转换
@Mapping(target = "emailaddress", qualifiedByName={"helperClass", "emailsToAddress"},
source = "emails")
在@Mapper的组件使用部分添加helperclass
@Mapper(
componentModel="spring",
uses ={
helperClass.class
},
)
helper类看起来像
@Component
@Named("helperClass")
public class helperClass {
@Named("emailsToAddress")
public String emailsToAddress(List<Email> emails) {
if(emails != null || !emails.isEmpty )
return emails.get(0).getAddress();
else
return null;
}
@组件
@命名(“帮助类”)
公共类帮助类{
@命名(“电子邮件地址”)
公共字符串emailsToAddress(列出电子邮件){
if(emails!=null | |!emails.isEmpty)
返回电子邮件。get(0)。getAddress();
其他的
返回null;
}
是的,我知道,但使用此解决方案,我必须为Iterable中包含的每个特定类型实现一个方法。我希望获得第一个元素,然后使用点符号访问此类型的字段。因此,我希望编写如下内容:@Mapping(target=“emailaddress”,source=“emails.emailaddress”,qualifiedBy=FirstElement.class),但也可以使用@Mapping(target=“prefix”,source=“phoneNumbers.prefix”,qualifiedBy=FirstElement.class),而无需为每个属性映射编写方法。例如,我想编写一个这样的映射程序:@Mapping(target=“emailaddress”,source=“emails[0].emailaddress”)你是对的。还有一种方法可以做到这一点。你可以使用@Maping
的expression
属性。例如@Mapping(target=“emailaddress”,expression=“emails!=null&&!emails.isEmpty()?emails.get(0).getEmailAddress():null”}
。如果电子邮件是映射方法的一部分,则可以使用电子邮件,如果电子邮件
是源参数的属性,则必须执行source.getEmails()
@Mapper(
componentModel="spring",
uses ={
helperClass.class
},
)
@Component
@Named("helperClass")
public class helperClass {
@Named("emailsToAddress")
public String emailsToAddress(List<Email> emails) {
if(emails != null || !emails.isEmpty )
return emails.get(0).getAddress();
else
return null;
}