Mapstruct - 字符串操作,但仅限于一个 属性

Mapstruct - String manipulation, but only on one property

我不确定我在这里遗漏了什么。我的自定义逻辑适用于我为目标指定的所有字符串属性,而不仅仅是一个属性。

@ApiModel(value="ShopProduct")
@Data
public class ShopProductDTO {
    private String description;
    private String fullImagePath;
}

@Entity
@Table(name = "shop_product")
public class ShopProduct implements Serializable {
    @Column(name = "desc")
    private String description;
    @Column(name = "thumb_path")
    private String thumbPath;
//getters,setters

ImageMapper:

@Component
public class ImagePathMapper {

    AppConfig appConfig;

    public ImagePathMapper(AppConfig appConfig) {
        this.appConfig = appConfig;
    }

    public String toFullImagePath(String thumbPath){
        return appConfig.getImagePath() + thumbPath;
    }
}

ShopProduct 映射器:

@Mapper(componentModel = "spring", uses = {ImagePathMapper.class})
@Component
public interface ShopProductMapper {
    @Mapping(target = "fullImagePath", source = "thumbPath")
    ShopProductDTO shopProductToShopProductDTO(ShopProduct shopProduct);

}

生成的mapstruct class:

        ShopProductDTO shopProductDTO = new ShopProductDTO();

        shopProductDTO.setDescription( imagePathMapper.toFullImagePath( shopProduct.getName() ) );

        shopProductDTO.setFullImagePath( imagePathMapper.toFullImagePath( shopProduct.getThumbPath() ) );

}

为什么描述字段也与 toFullImagePath 一起使用?

这个“@Mapping(target = “fullImagePath”, source = “thumbPath”)”不应该指定我只想更改 fullImagePath 吗?

这不是它的工作方式。

当你定义一个映射时,Mapstruct 会尝试将源对象中的每个 属性 映射到目标对象,主要基于 property name conventions.

当您定义 @Mapping 注释时,您是在向此基本映射指示 异常

在你的例子中,当你定义这个时:

@Mapping(target = "fullImagePath", source = "thumbPath")

您表示源对象中的 属性 thumbPath 应映射到目标对象中的 fullImagePath:这是必要的,因为它们具有不同的名称,否则映射不会成功。

另一方面,当您定义 uses=ImagePathMapper.class 属性时,您指示 Mapstruct 将每个定义为特定 Class 类型的 属性 转换,在此 String案例,在源对象中找到:只要 ShopProduct 中定义的所有字段都是 String,此映射器将应用于每个 属性.

如果您只想为一个字段应用映射器,您可以调用 custom mapping method, or use decorators, or the before and after mapping annotations,如下例所示:

@Mapper(componentModel = "spring", uses=AppConfig.class, injectionStrategy = InjectionStrategy.CONSTRUCTOR)
public abstract class ShopProductMapper {

  abstract ShopProductDTO shopProductToShopProductDTO(ShopProduct shopProduct);

  @Autowired
  public void setAppConfig(AppConfig appConfig) {
    this.appConfig = appConfig;
  }

  @AfterMapping
  public void toFullImagePath(@MappingTarget ShopProductDTO shopProductDTO, ShopProduct shopProduct) {
    String thumbPath = shopProduct.getThumbPath();
    if (thumbPath != null) {
      shopProductDTO.setFullImagePath(appConfig.getImagePath() + thumbPath);
    }
  }
}

请注意示例中您需要对映射器进行几处更改才能正常使用 Spring:请参阅 and this