java - 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 吗?
解决方案
这不是它的工作方式。
当你定义一个映射时, Mapstruct 将尝试将源对象中的每个属性映射到目标对象,主要基于属性名称约定。
当您定义@Mapping
注释时,您表示此基本映射的例外情况。
在您的示例中,当您定义此内容时:
@Mapping(target = "fullImagePath", source = "thumbPath")
您指出thumbPath
源对象中的属性应映射到fullImagePath
目标对象中的属性:这是必要的,因为它们具有不同的名称,否则映射将不会成功。
另一方面,当您定义uses=ImagePathMapper.class
属性时,您是在指示 Mapstruct 转换定义为某种Class
类型的每个属性,String
在这种情况下,在源对象中找到:只要定义的所有字段ShopProduct
都是String
s 这个映射器将被应用每个属性。
如果您只想将映射器应用于一个字段,您可以调用自定义映射方法,或使用装饰器,或映射前后的注释,如下例所示:
@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);
}
}
}
推荐阅读
- java - 如何在 Java 中编写一个接受一个泛型参数的方法,该参数可能是:一种类型、第二种类型或两种类型?(见示例)
- scala - 从 Mirror 获取 MirroredElemLabels
- angular - 如何减少模板上的异步管道订阅数量
- c++ - 一个向量索引处的多个元素
- python - 清理两列,然后合并为一个值
- javascript - Angular中的对象到数组
- typescript - 解构时如何指定更好的类型
- r - 为什么当 server = FALSE 时 selectizeInput 不选择第一个选项?
- typescript - 我可以在打字稿中测试另一个泛型类型的泛型类型吗?
- linux - 为什么我不能让 mv 重命名和复制文件?