Using ModelMapper on different data types with same attribute name

▼魔方 西西 提交于 2021-01-01 04:23:55

问题


I have two classes say Animal & AnimalDto
I want to use ModelMapper to convert Entity to DTO and vice verca.
But the classes are supposed to have different data types for a few attributes having similar name.
How do I achieve this?

Animal.java

public class Animal {    
    int category;    
    String color;    
    int age;
}    
 

AnimalDto.java

public class AnimalDto {    
    String category;    
    int color;    
    int age;
}

currently I'm manually transforming as such:

class AnimalTransformer {
    private static Category[] categories = Category.values();    
    private static Color[] colors = Color.values();    

    animalEntityToDto(Animal animal) {
          AnimalDto animalDto = new AnimalDto();    
          animalDto.setAge(animal.getAge());
          animalDto.setCategory(categories[animal.getCategory()].toString());
          animalDto.setColor(Color.valueOf(animal.getColor()).ordinal());
    }

    animalDtoToEntity(AnimalDto animalDto) {
          Animal animal = new Animal();    
          animal.setAge(animalDto.getAge());
          animal.setCategory(Category.valueOf(animalDto.getCategory()).ordinal());
          animal.setColor(colors[animalDto.getColor()].toString());
    }
}

回答1:


The example you presented might not be the best part of model mapper in fluency especially because converting enums that have some special difficulties what comes to using generics.

Anyway this is possible with Converter or usually AbstractConverter.

You did not provide examples of your enums so I create most simple example enums:

enum Color {
    PINK;
}

and

enum Category {
    MAMMAL;
}

To convert Integer Animal.category to String AnimalDto.category, a converter could be like:

public class CategoryToStringConverter extends AbstractConverter<Integer, String> {
    @Override
    protected String convert(Integer source) {
        return Category.values()[source].toString();
    }
}

And to convert String Animal.color to Integer AnimalDto.category, a converter could be like:

public class ColorToOrdinalConverter extends AbstractConverter<String, Integer> {
    @Override
    protected Integer convert(String source) {
        return Color.valueOf(source).ordinal();
    }
}

Usage would be like:

mm.createTypeMap(Animal.class, AnimalDto.class).addMappings(mapper -> {
    mapper.using(new CategoryToStringConverter()).map(Animal::getCategory, 
        AnimalDto::setCategory);
    mapper.using(new ColorToOrdinalConverter()).map(Animal::getColor, 
        AnimalDto::setColor);
});

This is the part of converting from Animal to AnimalDto. Converting vice versa of course needs mappings of its own which I do not present here because I think the point came clear.

For one class the way you do it now might be better but if you need to convert Category & Color in many places like this then you should consider using converters that are reusable.



来源:https://stackoverflow.com/questions/64604829/using-modelmapper-on-different-data-types-with-same-attribute-name

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!