MapStruct高级使用姿势

MapStruct是一个Java注解处理器,用于自动生成类型安全的、高性能的Java Bean映射器。它可以帮助我们在Java项目中实现对象之间的转换,而无需编写繁琐的映射代码。

target 和source

在 MapStruct 中,@Mapping(target = …, source = …) 是用于定义源对象(Source)到目标对象(Target)之间属性映射关系的注解。

target: target 属性指定了目标对象中的一个属性。这个属性将接收从源对象中转换或映射过来的值。例如:

@Mapping(target = "username", ...)

这里表示我们将映射一个值到目标对象的 username 属性上。
source: source 属性指定了源对象中的一个属性或方法。这个属性或方法的值将被转换或映射到目标对象的指定属性上。例如:

@Mapping(target = "username", source = "name")

这里表示我们将源对象的 name 属性的值映射到目标对象的 username 属性上。
如果源和目标属性的名字相同,你可以省略 source 属性,MapStruct 会自动匹配。例如:

@Mapping(target = "username")

这里表示我们将源对象的 username 属性的值映射到目标对象的 username 属性上,因为它们的名字相同,所以可以省略 source 属性。
示例:我们创建一个 UserMapper 接口来定义这些属性之间的映射关系:

@Mapper
public interface UserMapper {
    UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);
    @Mapping(target = "username", source = "name")
    @Mapping(target = "userAge", source = "age")
    UserDto toUserDto(User user);
}

在这个例子中,我们指定了两个映射关系:

target = “username” 和 source = “name” 表示将 User 对象的 name 属性映射到 UserDto 对象的 username 属性。
target = “userAge” 和 source = “age” 表示将 User 对象的 age 属性映射到 UserDto 对象的 userAge 属性。

dateFormat

dateFormat用来格式化时间类型成字符串:

  @Mapping(source = "createDate", target = "createDate", dateFormat = "yyyy/MM/dd")
    ProductDto toProductDto(Product product);

expression使用

expression 属性值是一个字符串,它会被解析为 Java 表达式,并在运行时执行。
使用expression时,其中必须为java()格式。
应用场景:我们在转换属性时,可能需要调用java里的甚至jar包中的各种工具类或者自定义方法产生新的数据:

@Mapper
public interface ProductMapper {

    @Mapping(target = "idBool",
            expression = "java( cn.hutool.core.util.StrUtil.isNotBlank( product.getId() ))")
    @Mapping(target = "price", expression = "java( java.math.BigDecimal.valueOf( product.getPrice() ))")
    
    ProductDto toProductDto(Product product);
}

想要ProductDto 对象中idBool显示product的Id是否存在,price字段转为BigDecimal类型。
查看生成的代码:

    productDto.setPrice( java.math.BigDecimal.valueOf( product.getPrice() ) );
        productDto.setIdBool( cn.hutool.core.util.StrUtil.isNotBlank( product.getId() ) );

示例替换ID方法:

@Mapping(target = "id", expression =
            "java( com.example.abount.interface1.ProductMapper.toId( product.getId() ))")
    ProductDto toProductDto(Product product);

    @Named("toId")
    static String toId(String id) {
        return "1";
    }

defaultExpression属性

当且仅当source属性为null的时候,将target指定的属性值设置为该表达式的值。不能同时和expression、defaultValue以及constant属性一起使用!

用法和expression属性类似,代码可以参考上面的例子,不再赘述。

qualifiedByName和conditionQualifiedByName

如果你的映射逻辑很复杂,或者涉及到多个步骤,那么可能需要使用自定义映射方法;如果你只需要一个简单的表达式就可以完成映射,那么可以直接使用 expression 属性。

  1. qualifiedByName的使用,自定义方法需要@Named注解:
@Mapper
public interface ProductMapper {


    ProductMapper INSTANCE = Mappers.getMapper(ProductMapper.class);

    @Mapping(target = "id", source = "id", qualifiedByName = "toId")
    ProductDto toProductDto(Product product);

    @Named("toId")
    static String toId(String id) {
        return "1";
    }
}

查看生成代码:

productDto.setId( ProductMapper.toId( product.getId() ) );
  1. conditionQualifiedByName的使用,condition表示条件判断,自定义方法需要@Named注解和@Condition:
@Mapper
public interface ProductMapper {
    ProductMapper INSTANCE = Mappers.getMapper(ProductMapper.class);

    @Condition
    @Named("showId")
    static boolean showId(String value) {
        return "333333".equals(value);
    }

    @Mapping(target = "id", source = "id", conditionQualifiedByName = "showId")
    ProductDto toProductDto(Product product);

    @Named("toId")
    static String toId(String id) {
        return "1";
    }
}

此时当只有ID为333333才能正常copy。

  • 12
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

π克

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值