Joh*_*lis 12 spring iterable mapstruct
我想将对象列表映射到包含列表的对象:
public class Group {
private List<Person> people;
}
public class Person {
private String name;
}
Run Code Online (Sandbox Code Playgroud)
我尝试创建一个这样的映射器:
Group toGroup(List<Person> people);
Run Code Online (Sandbox Code Playgroud)
我收到此错误:
error: Can't generate mapping method from iterable type to non-iterable type.
Run Code Online (Sandbox Code Playgroud)
这种映射最优雅的解决方案是什么?
Nil*_*oud 13
Mapstruct实际上可以做到。我有完全相同的情况,一个仅包含项目的 CollectionResponse。我通过添加一个虚拟参数来解决这个问题,如下所示:
@Mapper(componentModel = "spring", uses = ItemMapper.class)
public interface CollectionResponseMapper {
// Dummy property to prevent Mapstruct complaining "Can't generate mapping method from iterable type to non-iterable type."
@Mapping( target = "items", source = "items")
CollectionResponse map( Integer dummy, List<Item> items);
}
Run Code Online (Sandbox Code Playgroud)
Mapstruct 生成所需的代码。像这样的事情:
public class CollectionResponseMapperImpl implements CollectionResponseMapper {
@Autowired
private ItemMapper itemMapper;
@Override
public CollectionResponse map(Integer dummy, List<Item> items) {
if ( dummy == null && items == null ) {
return null;
}
CollectionResponse collectionResponse = new CollectionResponse();
if ( items != null ) {
collectionResponse.setItems( itemListToItemDtoList( items ) );
}
return collectionResponse;
}
protected List<ItemDto> itemListToItemDtoList(List<Item> list) {
if ( list == null ) {
return null;
}
List<ItemDto> list1 = new ArrayList<ItemDto>( list.size() );
for ( Item item : list ) {
list1.add( itemMapper.mapItemToDto( item ) );
}
return list1;
}
}
Run Code Online (Sandbox Code Playgroud)
一般回答 - 禁止此类映射。
要将对象列表映射到包装该列表的对象,可以通过以下方式完成:
/// your class with business code
List<Person> people = ....
new Group(people);
/// group class
public class Group {
private List<Person> people = new ArrayList<>();
public Group(List<Person> people) {
this.people = people
}
}
Run Code Online (Sandbox Code Playgroud)
当Group只有简单的构造函数并以列表作为参数时。您不需要为此使用 Mapstruct。在 Mapstruct 源中,检查MethodRetrievalProcessor.java 的 Mapstruct github 源:
Type parameterType = sourceParameters.get( 0 ).getType();
if ( parameterType.isIterableOrStreamType() && !resultType.isIterableOrStreamType() ) {
messager.printMessage( method, Message.RETRIEVAL_ITERABLE_TO_NON_ITERABLE );
return false;
}
Run Code Online (Sandbox Code Playgroud)
所以基本上,即使 Mapstruct 团队也希望您仅在需要时才使用映射。并且不想允许转变List<Object>为另一个Object,因为它没有意义。如果您要为对象添加一些附加信息(不可迭代:)),这将有意义Group,例如:
//group class
public class Group {
private Long someCounter;
private List<Person> people;
}
//mapper
@Mapping(target= "people", source ="people")
@Mapping(target= "someCounter", source ="counterValue")
Group toGroup(Long counterValue, List<Person> people);
Run Code Online (Sandbox Code Playgroud)
但最好使用 DTO、视图、实体和任何其他类型的对象来隐藏所有嵌套的内容。在这种情况下,Mapstruct 将是你最好的朋友。
| 归档时间: |
|
| 查看次数: |
21709 次 |
| 最近记录: |