使用 mapstruct 如何使用 spring 组件映射器将对象映射到对象列表
using mapstruct how to map an object to a list of objects with spring component mappers
我正在尝试将对象 A 映射到对象 B 的列表。
我有一个从对象 A 映射到对象 B 的映射器。
例如,我尝试了多种不同的方式
尝试使用 'expressions' 创建包含一个对象 A 的列表
'qualifiedByName' 但这行不通,因为我认为
当你使用 expressions/qualifiedByName 时你不能使用
自定义映射器(我在这里可能是错的?)
我还尝试使用 @aftermapper 方法调用映射器
获取目标映射器句柄的“mappers.getMapper”
但是我发现映射器中使用的 spring beans
没有人口的地方。 aftermapping 中的映射使得
感觉我可以用源代码调用目标映射器
然后将目标添加到列表中。所以我希望那里
是从我的映射器获取映射器组件句柄的另一种方法。
我所有的映射器都使用
@Mapper(componentModel="spring",
欢迎所有建议
下面是显示问题的代码示例。
此致,
德克兰
// SPECIESTOLOGSPECY.JAVA
// From this mapper I want to call SpecyToLogDeclarationMapperApi mapper
// to map ‘species’ to ‘logdeclarations’ which is a list of logdeclaration
// you can see want I am trying to do in the aftermapping method
// where I map species to logdeclaration and then put this into a list
// unfortunately I need other mapping components (ConfigMapperFromCode & SpecyToFishDeclarationMapperApi)
// to be autowired into SpecyToLogDeclarationMapperApi and this is not happening.
// is there another way to get a handle to the spring managed
// SpecyToLogDeclarationMapperApi mapper ?
@Mapper(componentModel="spring",
uses = {
ConfigMapperFromCode.class,
GeoInfoMapper.class,
SpecyToLogDeclarationMapperApi.class
})
public interface SpeciesToLogSpecy {
SpecyToLogDeclarationMapperApi MAPPER = Mappers.getMapper(SpecyToLogDeclarationMapperApi.class);
@Mappings(
{
@Mapping(target="createdate", expression = "java(java.sql.Timestamp.valueOf(java.time.LocalDateTime.now()))"),
@Mapping(target="speciesid", qualifiedByName={"ConfigMapperFromCode", "speciesIdFromCodeAsDecimal"}, source = "species.speciesCode"),
@Mapping(target="unitweight", constant = "1"),
@Mapping(target = "inactiveind", constant = "N"),
@Mapping(target = "unitdefaultind", constant = "Y"),
@Mapping(target = "sectiontypeid", expression = "java(new BigDecimal(ie.gov.agriculture.fisheries.logsheet.mapping.constants.MappingConstants.LOG_SPECIES_SECTION_TYPE_SHEETDECLARATION))"),
@Mapping(target = "unituomid", expression = "java(new BigDecimal(ie.gov.agriculture.fisheries.logsheet.mapping.constants.MappingConstants.LOGSHEET_CATCHUNITS_KG))"),
@Mapping(target="catchtypeid", qualifiedByName={"ConfigMapperFromCode", "returnCatchTypeId"}, source = "species.spType"),
@Mapping(target="legalfishsizetypeid", qualifiedByName={"ConfigMapperFromCode", "legalFishSizeTypeIdFromCode"}, source = "species.fishSizeClass"),
@Mapping(target="presenttypeid", qualifiedByName={"ConfigMapperFromCode", "presentationTypeIdFromCode"}, source = "species.presentation.presentationType"),
//@Mapping(target="logdeclarations", source = "species")
}
)
Logspecy speciesToLogspecy(Species species, @Context ExtraFields extraFields);
@AfterMapping
default void afterMap(@MappingTarget Logspecy logspecy, @Context ExtraFields extraFields){
Logdeclaration logDeclaration = MAPPER.SpeciesToLogDeclarations(species, extraFields);
List<Logdeclaration> logdeclarations = new ArrayList<Logdeclaration>();
logdeclarations.add(logDeclaration);
logSpecy.setLogdeclarations(logdeclarations);
{
// SPECYTOLOGDECLARATIONMAPPERAPI.JAVA
@Mapper(componentModel="spring",
uses = {
ConfigMapperFromCode.class,
SpecyToFishDeclarationMapperApi.class
}
)
public interface SpecyToLogDeclarationMapperApi {
@Mappings(
{
@Mapping(target="createdate", expression = "java(java.sql.Timestamp.valueOf(java.time.LocalDateTime.now()))"),
@Mapping(target="geartypeid", qualifiedByName={"ConfigMapperFromCode", "gearIdFromCode"}, source = "species.gearType"),
@Mapping(target="fishcount", source = "species.qty"),
@Mapping(target = "inactiveind", constant = "N"),
@Mapping(target="packagetypeid", qualifiedByName={"ConfigMapperFromCode", "packagingTypeIdFromCode"}, source = "species.presentation.packaging"),
@Mapping(target="packagecount", source = "species.presentation.pkgunit"),
@Mapping(target="avgpackageweight", source = "species.presentation.pkgUnitWeight"),
@Mapping(target="conversionfactor", source = "species.presentation.convFactor"),
@Mapping(target="fishdeclaration", source = "species.geoInfo")
}
)
Logdeclaration SpeciesToLogDeclarations (Species species, @Context ExtraFields extraFields);
问题是您正在尝试将 Species
映射到 List<Logdeclaration>
,而 MapStruct 找不到这样的映射方法。为了使其工作,您可以将以下方法添加到您的 SpecyToLogDeclarationMapperApi
:
default List<Logdeclaration> SpeciesToLogDeclarationsToList(Species species, @Context ExtraFields extraFields) {
if ( species == null ) {
return null;
}
Logdeclaration logDeclaration = SpeciesToLogDeclarations(species, extraFields);
List<Logdeclaration> logdeclarations = new ArrayList<Logdeclaration>();
logdeclarations.add(logDeclaration);
return logdeclarations;
}
这是一些额外的东西,我认为你可以做这些来改进你的代码并使用 MapStruct "more correctly":
- 当组件模型不是
default
时,您需要删除 Mappers#getMapper(Class)
的用法
- 如果您不想在表达式中使用 FQN,可以使用
Mapper#imports
,MapStruct 将在实现中导入它们。
- 当您只有一个源参数时,您不必在映射中使用它的名称
例如
@Mapping(target="fishcount", source = "species.qty")
可以是
@Mapping(target="fishcount", source = "qty")
我正在尝试将对象 A 映射到对象 B 的列表。 我有一个从对象 A 映射到对象 B 的映射器。
例如,我尝试了多种不同的方式 尝试使用 'expressions' 创建包含一个对象 A 的列表 'qualifiedByName' 但这行不通,因为我认为 当你使用 expressions/qualifiedByName 时你不能使用 自定义映射器(我在这里可能是错的?)
我还尝试使用 @aftermapper 方法调用映射器 获取目标映射器句柄的“mappers.getMapper” 但是我发现映射器中使用的 spring beans 没有人口的地方。 aftermapping 中的映射使得 感觉我可以用源代码调用目标映射器 然后将目标添加到列表中。所以我希望那里 是从我的映射器获取映射器组件句柄的另一种方法。
我所有的映射器都使用
@Mapper(componentModel="spring",
欢迎所有建议 下面是显示问题的代码示例。
此致, 德克兰
// SPECIESTOLOGSPECY.JAVA
// From this mapper I want to call SpecyToLogDeclarationMapperApi mapper
// to map ‘species’ to ‘logdeclarations’ which is a list of logdeclaration
// you can see want I am trying to do in the aftermapping method
// where I map species to logdeclaration and then put this into a list
// unfortunately I need other mapping components (ConfigMapperFromCode & SpecyToFishDeclarationMapperApi)
// to be autowired into SpecyToLogDeclarationMapperApi and this is not happening.
// is there another way to get a handle to the spring managed
// SpecyToLogDeclarationMapperApi mapper ?
@Mapper(componentModel="spring",
uses = {
ConfigMapperFromCode.class,
GeoInfoMapper.class,
SpecyToLogDeclarationMapperApi.class
})
public interface SpeciesToLogSpecy {
SpecyToLogDeclarationMapperApi MAPPER = Mappers.getMapper(SpecyToLogDeclarationMapperApi.class);
@Mappings(
{
@Mapping(target="createdate", expression = "java(java.sql.Timestamp.valueOf(java.time.LocalDateTime.now()))"),
@Mapping(target="speciesid", qualifiedByName={"ConfigMapperFromCode", "speciesIdFromCodeAsDecimal"}, source = "species.speciesCode"),
@Mapping(target="unitweight", constant = "1"),
@Mapping(target = "inactiveind", constant = "N"),
@Mapping(target = "unitdefaultind", constant = "Y"),
@Mapping(target = "sectiontypeid", expression = "java(new BigDecimal(ie.gov.agriculture.fisheries.logsheet.mapping.constants.MappingConstants.LOG_SPECIES_SECTION_TYPE_SHEETDECLARATION))"),
@Mapping(target = "unituomid", expression = "java(new BigDecimal(ie.gov.agriculture.fisheries.logsheet.mapping.constants.MappingConstants.LOGSHEET_CATCHUNITS_KG))"),
@Mapping(target="catchtypeid", qualifiedByName={"ConfigMapperFromCode", "returnCatchTypeId"}, source = "species.spType"),
@Mapping(target="legalfishsizetypeid", qualifiedByName={"ConfigMapperFromCode", "legalFishSizeTypeIdFromCode"}, source = "species.fishSizeClass"),
@Mapping(target="presenttypeid", qualifiedByName={"ConfigMapperFromCode", "presentationTypeIdFromCode"}, source = "species.presentation.presentationType"),
//@Mapping(target="logdeclarations", source = "species")
}
)
Logspecy speciesToLogspecy(Species species, @Context ExtraFields extraFields);
@AfterMapping
default void afterMap(@MappingTarget Logspecy logspecy, @Context ExtraFields extraFields){
Logdeclaration logDeclaration = MAPPER.SpeciesToLogDeclarations(species, extraFields);
List<Logdeclaration> logdeclarations = new ArrayList<Logdeclaration>();
logdeclarations.add(logDeclaration);
logSpecy.setLogdeclarations(logdeclarations);
{
// SPECYTOLOGDECLARATIONMAPPERAPI.JAVA
@Mapper(componentModel="spring",
uses = {
ConfigMapperFromCode.class,
SpecyToFishDeclarationMapperApi.class
}
)
public interface SpecyToLogDeclarationMapperApi {
@Mappings(
{
@Mapping(target="createdate", expression = "java(java.sql.Timestamp.valueOf(java.time.LocalDateTime.now()))"),
@Mapping(target="geartypeid", qualifiedByName={"ConfigMapperFromCode", "gearIdFromCode"}, source = "species.gearType"),
@Mapping(target="fishcount", source = "species.qty"),
@Mapping(target = "inactiveind", constant = "N"),
@Mapping(target="packagetypeid", qualifiedByName={"ConfigMapperFromCode", "packagingTypeIdFromCode"}, source = "species.presentation.packaging"),
@Mapping(target="packagecount", source = "species.presentation.pkgunit"),
@Mapping(target="avgpackageweight", source = "species.presentation.pkgUnitWeight"),
@Mapping(target="conversionfactor", source = "species.presentation.convFactor"),
@Mapping(target="fishdeclaration", source = "species.geoInfo")
}
)
Logdeclaration SpeciesToLogDeclarations (Species species, @Context ExtraFields extraFields);
问题是您正在尝试将 Species
映射到 List<Logdeclaration>
,而 MapStruct 找不到这样的映射方法。为了使其工作,您可以将以下方法添加到您的 SpecyToLogDeclarationMapperApi
:
default List<Logdeclaration> SpeciesToLogDeclarationsToList(Species species, @Context ExtraFields extraFields) {
if ( species == null ) {
return null;
}
Logdeclaration logDeclaration = SpeciesToLogDeclarations(species, extraFields);
List<Logdeclaration> logdeclarations = new ArrayList<Logdeclaration>();
logdeclarations.add(logDeclaration);
return logdeclarations;
}
这是一些额外的东西,我认为你可以做这些来改进你的代码并使用 MapStruct "more correctly":
- 当组件模型不是
default
时,您需要删除 - 如果您不想在表达式中使用 FQN,可以使用
Mapper#imports
,MapStruct 将在实现中导入它们。 - 当您只有一个源参数时,您不必在映射中使用它的名称
Mappers#getMapper(Class)
的用法
例如
@Mapping(target="fishcount", source = "species.qty")
可以是
@Mapping(target="fishcount", source = "qty")