当前位置: 首页 > article >正文

MapperStruct的高级用法

MapperStruct是一个非常好用的Bean映射工具,虽然还需要去维护一个接口来进行映射,但是其bean对象的映射却是非常的高效,另外它还提供了提供了许多自定义的配置,方便我们在各种场景下灵活使用!

定义映射器

基本映射器

如果目标对象与源对象属性不一致,则需要明确指定属性名

@Mapper
public interface CarMapper {

    @Mapping(target = "manufacturer", source = "make")
    @Mapping(target = "seatCount", source = "numberOfSeats")
    CarDto carToCarDto(Car car);

    @Mapping(target = "fullName", source = "name")
    PersonDto personToPersonDto(Person person);
}

表达式

指定目标对象使用指定表达式赋值

@Mapping(target = "creationDate", expression = "java(new java.util.Date())")

 自定义方法

如果复制对象内部有引用类型的成员,可自定义方法,完成引用类型之间的对应拷贝。

@Mapper
public interface CarMapper {

    @Mapping(...)
    ...
    CarDto carToCarDto(Car car);

    default PersonDto personToPersonDto(Person person) {
        //hand-written mapping logic
    }
}

多个源对象

源数据来源多个对象

@Mapper
public interface AddressMapper {

    @Mapping(target = "description", source = "person.description")
    @Mapping(target = "houseNumber", source = "address.houseNo")
    DeliveryAddressDto personAndAddressToDeliveryAddressDto(Person person, Address address);
}

源数据来源普通参数

@Mapper
public interface AddressMapper {

    @Mapping(target = "description", source = "person.description")
    @Mapping(target = "houseNumber", source = "hn")
    DeliveryAddressDto personAndAddressToDeliveryAddressDto(Person person, Integer hn);

}

嵌套对象属性

如果复制对象内部有相同的引用类型,指定成员属性名,可直接复制。如果不同,则需要明确指定成员变量的某个属性,对应另一个对象的某个成员属性的某个属性。 

@Mapper
 public interface CustomerMapper {

     @Mapping( target = "name", source = "record.name" )
     @Mapping( target = ".", source = "record" )
     @Mapping( target = ".", source = "account" )
     Customer customerDtoToCustomer(CustomerDto customerDto);
 }

 更新bean实例

通过 @MappingTarget 注解,更新实例。 

@Mapper
public interface CarMapper {

    void updateCarFromDto(CarDto carDto, @MappingTarget Car car);

}

 public访问权限修饰符修饰的成员

public class Customer {

    private Long id;
    private String name;

    //getters and setter omitted for brevity
}

public class CustomerDto {

    public Long id;
    public String customerName;
}

@Mapper
public interface CustomerMapper {

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

    @Mapping(target = "name", source = "customerName")
    Customer toCustomer(CustomerDto customerDto);

    @InheritInverseConfiguration
    CustomerDto fromCustomer(Customer customer);
}

构造器

MapStruct 支持使用构造函数来映射目标类型。执行映射时,MapStruct 会检查所映射的类型是否有构建器。如果没有构建器,则 MapStruct 会查找单个可访问的构造函数。当有多个构造函数时,执行以下操作来选择应该使用的构造函数:

  • 如果构造函数使用名为 @Default 的注释进行批注,则将使用该批注。
  • 如果存在单个公共构造函数,则将使用该构造函数构造对象,而忽略其他非公共构造函数。
  • 如果存在无参数构造函数,则它将用于构造对象,其他构造函数将被忽略。
  • 如果有多个符合条件的构造函数,则由于构造函数不明确,将出现编译错误。为了打破歧义,可以使用名为 @Default 的注释

映射Map到Bean 

指定Map的key映射到对应Bean的属性。

public class Customer {

    private Long id;
    private String name;

    //getters and setter omitted for brevity
}

@Mapper
public interface CustomerMapper {

    // 此时map对象中包括键customerName
    @Mapping(target = "name", source = "customerName")
    Customer toCustomer(Map<String, String> map);

}

获取映射器示例

通过映射工厂获取实例

CarMapper mapper = Mappers.getMapper( CarMapper.class );

数据类型转化

隐式类型转化

8种基本类型与其包装类,可以自动转化。
8种基本类型与String,可以自动转化。

数字格式化

@Mapper
public interface CarMapper {

    @Mapping(source = "price", numberFormat = "$#.00")
    CarDto carToCarDto(Car car);

    @IterableMapping(numberFormat = "$#.00")
    List<String> prices(List<Integer> prices);
}

日期格式化

@Mapper
public interface CarMapper {

    @Mapping(source = "manufacturingDate", dateFormat = "dd.MM.yyyy")
    CarDto carToCarDto(Car car);

    @IterableMapping(dateFormat = "dd.MM.yyyy")
    List<String> stringListToDateList(List<Date> dates);
}

引用类型映射

明确指定属性即可完成复制。

嵌套类型映射

通过明确指定的属性值,完成复制。

调用其他映射器

定义公用映射器

  public class DateMapper {

      public String asString(Date date) {
          return date != null ? new SimpleDateFormat( "yyyy-MM-dd" ).format( date ) : null;
      }

      public Date asDate(String date) {
          try {
              return date != null ? new SimpleDateFormat( "yyyy-MM-dd" ).parse( date ) : null;
          } catch ( ParseException e ) {
              throw new RuntimeException( e );
          }
      }
  }

使用

  @Mapper(uses=DateMapper.class)
  public interface CarMapper {

      CarDto carToCarDto(Car car);
  }

限定符结合默认值

使用限定符指定生成默认值方法

  @Mapper
  public interface MovieMapper {

       @Mapping( target = "category", qualifiedByName = "CategoryToString", defaultValue = "DEFAULT" )
       GermanRelease toGerman( OriginalRelease movies );

       @Named("CategoryToString")
       default String defaultValueForQualifier(Category cat) {
           // some mapping logic
       }
  }

此时 category 为空时,将使用 defaultValueForQualifier 方法生成默认值。


http://www.kler.cn/news/155722.html

相关文章:

  • 阿里微服务质量保障系列:性能监控最佳实践
  • 命令模式-C++实现
  • 超硬核解析Mybatis动态代理原理!只有接口没实现也能跑?
  • Python WebSocket 客户端教程
  • maven如何用命令看配置文件位置
  • 如何绕过某讯手游保护系统并从内存中获取Unity3D引擎的Dll文件
  • Debian12配置ssh服务器
  • 用Java写一个王者荣耀游戏
  • Django rest froamwork-序列化关系
  • python 交互模式和命令行模式的问题
  • 【C++】类和对象——explicit关键字,友元和内部类
  • Linux(12):磁盘配额(Quota)与进阶文件系统管理
  • Linux系统中进程间通信(Inter-Process Communication, IPC)
  • 医院电子病历编辑器源码(支持云端SaaS服务)
  • 关于清空ant.design 中表单内容的方法
  • 分享77个焦点幻灯JS特效,总有一款适合您
  • 【llm使用】ChatGLM3-6B Transformers部署调用
  • 【力扣206】反转链表
  • Filebeat使用指南
  • RPA机器人如何确保敏感数据的安全性
  • 使用 OpenCV 识别和裁剪黑白图像上的白色矩形--含源码
  • 策略设计模式
  • Spring Boot 3.2 新特性之 RestClient
  • 【C语言】【数据结构】【手搓二叉树】用数组实现一个二叉树
  • Android 第三十九章 RatingBar
  • SpringMVC常用注解和用法总结
  • leetcode:468. 验证IP地址
  • viple模拟器使用(四):unity模拟器中实现两距离局部最优迷宫算法
  • javaee实验:文件上传及截器的使用
  • 迭代器模式-C++实现