首页 > 解决方案 > Mapstruct - 字符串操作,但仅限于一个属性

问题描述

我不确定我在这里缺少什么。我的自定义逻辑适用于我为 target 指定的所有 String 属性,而不仅仅是一个属性。

@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

图像映射器:

@Component
public class ImagePathMapper {

    AppConfig appConfig;

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

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

店铺产品映射器:

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

}

生成的mapstruct类:

        ShopProductDTO shopProductDTO = new ShopProductDTO();

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

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

}

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

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

标签: javaspring-bootmapstruct

解决方案


这不是它的工作方式。

当你定义一个映射时, Mapstruct 将尝试将源对象中的每个属性映射到目标对象,主要基于属性名称约定

当您定义@Mapping注释时,您表示此基本映射的例外情况。

在您的示例中,当您定义此内容时:

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

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

另一方面,当您定义uses=ImagePathMapper.class属性时,您是在指示 Mapstruct 转换定义为某种Class类型的每个属性,String在这种情况下,在源对象中找到:只要定义的所有字段ShopProduct都是Strings 这个映射器将被应用每个属性。

如果您只想将映射器应用于一个字段,您可以调用自定义映射方法,或使用装饰器,或映射前后的注释,如下例所示:

@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 一起正常工作:请参阅thisthis


推荐阅读