MapStruct:如何将所有属性映射到列表的第一个元素?
MapStruct: How to map all attributes to first element of a list?
我需要一个映射来实现:
@Mapping(source = "a", target = "result.transactions[0].a"),
@Mapping(source = "b", target = "result.transactions[0].b"),
@Mapping(source = "c", target = "result.transactions[0].c"),
...
Response dataToResponse(DataModel model);
但是这种语法不起作用(顺便说一句:这适用于 Spring Bean 包装器)。
像this这样的解决方案只是半生不熟的解决方案:
@AsList
public <T> List<T> asList( T in ) {
List<T> result = new ArrayList<T>();
if ( in!=null ) {
result.add(in);
}
return result;
}
这只适用于一个属性,因为它总是为每个属性创建一个新列表。我不需要将每个属性映射到新列表的第一个元素。该列表必须重复使用,但我不知道它是如何工作的。实现这一目标的正确方法是什么?
我想到了这样的事情:
@Mapping(source = "a", target = "transaction.a"),
@Mapping(source = "b", target = "transaction.b"),
@Mapping(source = "c", target = "transaction.c"),
...
Transaction dataToTransaction(DataModel model);
然后...
@Mapping([use Transaction from b4], target = "result");
但是我怎样才能从上面传递已经映射的字段呢?
(我使用的是最新的最终版本 1.1。0.Final)
显然没有干净的解决方案。所以我不得不通过将以下映射排除到单独的映射器中来解决它:
@Mapping(source = "a", target = "transaction.a"),
@Mapping(source = "b", target = "transaction.b"),
@Mapping(source = "c", target = "transaction.c"),
Transaction dataToTransaction(DataModel model);
在主映射器中,我执行单独的映射器并通过表达式将其转换为列表:
@Mapping(expression = "java(Arrays.asList(SubMapper.INSTANCE.dataToTransaction(model)))", target = "result.transactions")
刚刚遇到这个问题。更优雅的解决方案是这样的:
@Mapping(source = "a", target = "transaction.a"),
@Mapping(source = "b", target = "transaction.b"),
@Mapping(source = "c", target = "transaction.c"),
Transaction dataToTransaction(DataModel model);
- 这个和之前的回答一样
剩下要做的是将单个事务映射到单元素列表:
default List<Transaction> mapTransactionToList(Transaction source) {
return ImmutableList.of(source);
}
现在您可以简单地将 model
映射到 @Mapping
定义中的 List<Transaction>
并且 MapStruct 应该知道要做什么。
我认为这看起来比基于 "expression" 的解决方案更好并且更不容易出错。
请注意,您可以在 Mapper 接口中包含代码。
我认为使用表达式是这里的解决方法:
public interface MyMapper {
@Mapping(target = "subjectName", expression = "java(source.getCourses().get(0).getCourseName())")
Target map(Source source);
}
另请查看此处了解更多信息:
https://github.com/mapstruct/mapstruct/issues/1321
在我的代码中我是这样做的:
@Mapping(expression = "java(player.getAddressBooks().get(0).getPostCode())", target = "postCode")
@Mapping(expression = "java(player.getAddressBooks().get(0).getCity())", target = "city")
@Mapping(expression = "java(player.getAddressBooks().get(0).getStreetNumber())", target = "streetNumber")
@Mapping(expression = "java(player.getAddressBooks().get(0).getStreetName())", target = "streetName")
@Mapping(expression = "java(player.getAddressBooks().get(0).getCountryISO())", target = "countryISO")
我需要一个映射来实现:
@Mapping(source = "a", target = "result.transactions[0].a"),
@Mapping(source = "b", target = "result.transactions[0].b"),
@Mapping(source = "c", target = "result.transactions[0].c"),
...
Response dataToResponse(DataModel model);
但是这种语法不起作用(顺便说一句:这适用于 Spring Bean 包装器)。 像this这样的解决方案只是半生不熟的解决方案:
@AsList
public <T> List<T> asList( T in ) {
List<T> result = new ArrayList<T>();
if ( in!=null ) {
result.add(in);
}
return result;
}
这只适用于一个属性,因为它总是为每个属性创建一个新列表。我不需要将每个属性映射到新列表的第一个元素。该列表必须重复使用,但我不知道它是如何工作的。实现这一目标的正确方法是什么? 我想到了这样的事情:
@Mapping(source = "a", target = "transaction.a"),
@Mapping(source = "b", target = "transaction.b"),
@Mapping(source = "c", target = "transaction.c"),
...
Transaction dataToTransaction(DataModel model);
然后...
@Mapping([use Transaction from b4], target = "result");
但是我怎样才能从上面传递已经映射的字段呢? (我使用的是最新的最终版本 1.1。0.Final)
显然没有干净的解决方案。所以我不得不通过将以下映射排除到单独的映射器中来解决它:
@Mapping(source = "a", target = "transaction.a"),
@Mapping(source = "b", target = "transaction.b"),
@Mapping(source = "c", target = "transaction.c"),
Transaction dataToTransaction(DataModel model);
在主映射器中,我执行单独的映射器并通过表达式将其转换为列表:
@Mapping(expression = "java(Arrays.asList(SubMapper.INSTANCE.dataToTransaction(model)))", target = "result.transactions")
刚刚遇到这个问题。更优雅的解决方案是这样的:
@Mapping(source = "a", target = "transaction.a"),
@Mapping(source = "b", target = "transaction.b"),
@Mapping(source = "c", target = "transaction.c"),
Transaction dataToTransaction(DataModel model);
- 这个和之前的回答一样
剩下要做的是将单个事务映射到单元素列表:
default List<Transaction> mapTransactionToList(Transaction source) {
return ImmutableList.of(source);
}
现在您可以简单地将 model
映射到 @Mapping
定义中的 List<Transaction>
并且 MapStruct 应该知道要做什么。
我认为这看起来比基于 "expression" 的解决方案更好并且更不容易出错。
请注意,您可以在 Mapper 接口中包含代码。
我认为使用表达式是这里的解决方法:
public interface MyMapper {
@Mapping(target = "subjectName", expression = "java(source.getCourses().get(0).getCourseName())")
Target map(Source source);
}
另请查看此处了解更多信息: https://github.com/mapstruct/mapstruct/issues/1321
在我的代码中我是这样做的:
@Mapping(expression = "java(player.getAddressBooks().get(0).getPostCode())", target = "postCode")
@Mapping(expression = "java(player.getAddressBooks().get(0).getCity())", target = "city")
@Mapping(expression = "java(player.getAddressBooks().get(0).getStreetNumber())", target = "streetNumber")
@Mapping(expression = "java(player.getAddressBooks().get(0).getStreetName())", target = "streetName")
@Mapping(expression = "java(player.getAddressBooks().get(0).getCountryISO())", target = "countryISO")