【问题标题】:How to use Explicit Map with Java 8 and ModelMapper?如何在 Java 8 和 ModelMapper 中使用显式映射?
【发布时间】:2018-02-27 08:08:28
【问题描述】:

我通过官方文档http://modelmapper.org/getting-started/学习了如何使用ModelMapper

有使用 java 8 进行显式映射的代码示例

modelMapper.addMappings(mapper -> {
  mapper.map(src -> src.getBillingAddress().getStreet(),
      Destination::setBillingStreet);
  mapper.map(src -> src.getBillingAddress().getCity(),
      Destination::setBillingCity);
});

如何正确使用这段代码?当我在 IDE 中键入此代码 sn-p 时,IDE 会显示消息 cannot resolve method map

【问题讨论】:

    标签: java java-8 modelmapper


    【解决方案1】:

    他们在这个例子中遗漏了一步,他们使用的addMappings 方法是来自TypeMapaddMappings,而不是来自ModelMapper。您需要为您的 2 个对象定义一个 TypeMap。这样:

    // Create your mapper
    ModelMapper modelMapper = new ModelMapper();
    
    // Create a TypeMap for your mapping
    TypeMap<Order, OrderDTO> typeMap = 
        modelMapper.createTypeMap(Order.class, OrderDTO.class);
    
    // Define the mappings on the type map
    typeMap.addMappings(mapper -> {
        mapper.map(src -> src.getBillingAddress().getStreet(), 
                          OrderDTO::setBillingStreet);
        mapper.map(src -> src.getBillingAddress().getCity(), 
                          OrderDTO::setBillingCity);
    });
    

    另一种方法是使用ModelMapper 中的addMappings 方法。它不使用 lambdas 并采用PropertyMap。它也足够短:

    ModelMapper modelMapper = new ModelMapper();
    modelMapper.addMappings(new PropertyMap<Order, OrderDTO>() {
      @Override
      protected void configure() {
        map().setBillingStreet(source.getBillingAddress().getStreet());
        map().setBillingCity(source.getBillingAddress().getCity());
      }
    });
    

    【讨论】:

    • 我希望 java 库的作者能够明确地提供他们的示例。我在这个页面上挖掘了三天,试图找出如何做到这一点。
    • 任何想法为什么第一种方法会引发错误但第二种方法有效......?顺便说一句,这是我的情况
    • @ManuelGonçalves 你得到什么错误?编译错误,还是运行时错误?它是什么?
    【解决方案2】:

    如果源和目标类型不同。例如,

    @Entity
    class Student {
        private Long id;
        
        @OneToOne
        @JoinColumn(name = "laptop_id")
        private Laptop laptop;
    }
    

    和 Dto ->

    class StudentDto {
        private Long id;
        private LaptopDto laptopDto;
    }
    

    在这里,源类型和目标类型是不同的。因此,如果您的 MatchingStrategies 是 STRICT,您将无法在这两种不同类型之间进行映射。 现在要解决这个问题,只需将下面的代码放在控制器类的构造函数中或您要使用 ModelMapper 的任何类中->

    private ModelMapper modelMapper;
    
    public StudentController(ModelMapper modelMapper) {
        this.modelMapper = modelMapper;
        this.modelMapper.typeMap(Student.class, StudentDto.class).addMapping(Student::getLaptop, StudentDto::setLaptopDto);
    }
            
    

    就是这样。现在您可以轻松使用 ModelMapper.map(source, destination)。它会自动映射

    modelMapper.map(student, studentDto);
    

    【讨论】:

    • 我偶然发现了这个答案。我自己正在寻找一个解决方案,它恰好是针对类似问题但不完全相同的问题。我正在寻找stackoverflow.com/questions/64604829/… 的解决方案,对此有什么可能的解决方案?
    猜你喜欢
    • 1970-01-01
    • 2019-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-31
    • 2014-06-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多