• Java实体映射工具MapStruct使用详解


    1.序

    通常在后端开发中经常不直接返回实体Entity类,经过处理转换返回前端,前端提交过来的对象也需要经过转换Entity实体才做存储;通常使用的BeanUtils.copyProperties方法也比较粗暴,不仅效率低下(使用反射)而且仅映射相同名的属性,多数情况下还需要手动编写对应的转换方法实现。
    插件MapStruct以接口方法结合注解优雅实现对象转换,MapStruct生成器生成代码以更贴近原生的Setter、Getter方法处理属性映射更为高效。

    2.简单用例

    实体对象User

    1. @Data
    2. @AllArgsConstructor
    3. public class User {
    4. private int id;
    5. private String name;
    6. private int age;
    7. private String address;
    8. }

    转换对象UserVO

    1. @Data
    2. public class UserVO {
    3. private String userName;
    4. private int age;
    5. }

    转换接口

    1. @Mapper
    2. public interface UserConvert {
    3. UserConvert INSTANCE = Mappers.getMapper(UserConvert.class);
    4. @Mapping(source = "name", target = "userName")
    5. UserVO toVO(User entity);
    6. }

    使用示例

    1. @Test
    2. public void contextLoads() {
    3. User user = new User(0, "Tester", 1, "上海市徐汇区");
    4. UserVO userVO = UserConvert.INSTANCE.toVO(user);
    5. }

    3.使用详解

    1)关于接口注解@Mapper几种属性用法详解

    uses 使用其他手动编写的或者其他Mapper接口覆写相关的转换方法,不能循环引用

    @Mapper(uses=DateMapper.class)
    

    imports 引用相关类,允许通过mapping.expression()mapping.defaultExpression()直接使用这些类型

    1. @Mapper(imports = DateUtil.class)
    2. public interface UserConvert {
    3. UserConvert INSTANCE = Mappers.getMapper(UserConvert.class);
    4. @Mappings({
    5. @Mapping(source = "name", target = "userName"),
    6. // 以指定方法转换属性,这里如果不使用imports,则需要写全引用类包路径
    7. @Mapping(target = "birthday", expression = "java(DateUtil.formatDate(entity.getBirthday()))")
    8. })
    9. UserVO toVO(User entity);
    10. }

    unmappedSourcePolicyunmappedTargetPolicy 针对源类型/目标类型中未映射属性的反馈策略
    typeConversionPolicy 针对有损转换的反馈策略,例如Long转Integer
    反馈策略主要有三种:IGNORE,默认值,忽略未映射的字段。WARN,警告。ERROR,报错

    @Mapper(unmappedSourcePolicy = ReportingPolicy.ERROR)
    

    componentModel 指定生成映射器实例的模式,主要有四种:
    default,不主动生成实例,通常以Mappers.getMapper(Class)实例化。
    cdi,以CDI标准实例化映射器,使用@Inject注入相关实例,
    spring,Spring Bean方式实例化,
    jsr330,jsr330标准实例化

    1. @Mapper(componentModel = "spring")
    2. public interface UserConvert {
    3. @Mapping(source = "name", target = "userName")
    4. UserVO toVO(User entity);
    5. }
    1. @Autowired
    2. private UserConvert userConvert;

    implementationName 指定实现类名称,映射生成器接口会自动生成实现类Impl,使用此属性可避免类冲突
    implementationPackage 指定实现类包路径

    config 指定配置类,由指定的@MapperConfig配置类,config导入相关配置
    配置类

    1. @MapperConfig(
    2. uses = DateUtil.class,
    3. unmappedSourcePolicy = ReportingPolicy.WARN
    4. )
    5. public interface UserConfig {
    6. }

    导入配置类

    @Mapper(componentModel = "spring", config = UserConfig.class)
    

    collectionMappingStrategy 集合映射策略,这里注意集合映射时,如果集合中的类型已有对应转换方法,集合转换时会优先使用

    1. @Mappings({
    2. @Mapping(source = "name", target = "userName"),
    3. @Mapping(target = "birthday", expression = "java(DateUtil.formatDate(entity.getBirthday()))")
    4. })
    5. UserVO toVO(User entity);
    6. List collectionCvt(List entities);

    GENERATED CODE 生成器生成代码

    1. public List collectionCvt(List entities) {
    2. if (entities == null) {
    3. return null;
    4. } else {
    5. List list = new ArrayList(entities.size());
    6. Iterator var3 = entities.iterator();
    7. while(var3.hasNext()) {
    8. User user = (User)var3.next();
    9. // 集合转换时优先使用了已定义的toVO方法
    10. list.add(this.toVO(user));
    11. }
    12. return list;
    13. }
    14. }

    nullValueMappingStrategy null作为源值映射策略;RETURN_NULL默认返回null, RETURN_DEFAULT返回默认值,对于对象会通过构造器自动构造对象返回,集合会返回空集合

    当值为RETURN_DEFAULT时,如果映射规则中包含Mapping.expression、Mapping.constant必须手动判空处理,否则NPE

    @MapperConfig(nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT)
    

    NullValuePropertyMappingStrategy null作为源属性映射策略;SET_TO_NULL默认返回null,SET_TO_DEFAULT返回默认值,IGNORE 忽略该值,以目标对象已存在的值为准

    MappingInheritanceStrategy 继承方法级映射配置策略:EXPLICIT 显示使用InheritConfiguration生效。AUTO_INHERIT_FROM_CONFIG 自动继承正向转换的配置。AUTO_INHERIT_REVERSE_FROM_CONFIG 自动继承反向转换的配置。AUTO_INHERIT_ALL_FROM_CONFIG 都继承

    1. @MapperConfig(
    2. mappingInheritanceStrategy = MappingInheritanceStrategy.EXPLICIT
    3. )
    1. @InheritConfiguration
    2. void cvtVO(User entity, @MappingTarget UserVO vo);

    nullValueCheckStrategy 空值监测策略

    2) 其他方法级别注解

    @InheritInverseConfiguration 反向转换时继承映射规则

    @Mapping 配置类型属性的映射规则;
    dateFormat 格式化日期

    @Mapping(target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss")
    

    numberFormat 数字格式化

    @Mapping(target = "price", numberFormat = "$#.00")
    

    constant 常量

    @Mapping(target = "age", constant = "0")
  • 相关阅读:
    浅谈嵌入式系统的持续集成
    语法练习:pos_neg
    docker镜像原理
    【C++】面向对象编程(三)定义一个“抽象基类”的三大步骤
    第 397 场 LeetCode 周赛题解
    EMQX +计算巢:构建云上物联网平台,轻松实现百万级设备连接
    Redis的哨兵机制,一文全解
    ch4-2 音频信号的时域特征
    音频和视频如何同步?Red Giant PluralEyes Mac
    mycat 垂直分库与水平分表使用详解
  • 原文地址:https://blog.csdn.net/guanshengg/article/details/126545276