Картографски списъци с ModelMapper

1. Общ преглед

В този урок ще обясним как да картографираме списъци с различни типове елементи, използвайки рамката ModelMapper. Това включва използването на родови типове в Java като решение за преобразуване на различни типове данни от един списък в друг .

2. Модел Mapper

Основната роля на ModelMapper е да картографира обекти, като определя как един обектен модел се съпоставя с друг, наречен Data Transformation Object (DTO).

За да използваме ModelMapper, започваме с добавяне на зависимостта към нашия pom.xml :

 org.modelmapper modelmapper 2.3.7 

2.1. Конфигурация

ModelMapper предоставя разнообразни конфигурации за опростяване на процеса на картографиране. Ние персонализираме конфигурацията, като активираме или деактивираме съответните свойства в конфигурацията. Това е често срещана практика, за да зададете fieldMatchingEnabled имота да е вярно и да позволи на частни поле съвпадение :

modelMapper.getConfiguration() .setFieldMatchingEnabled(true) .setFieldAccessLevel(Configuration.AccessLevel.PRIVATE); 

По този начин ModelMapper може да сравнява частни полета в класовете за картографиране (обекти). В тази конфигурация не е абсолютно необходимо всички полета с еднакви имена да съществуват и в двата класа. Разрешени са няколко стратегии за съвпадение. По подразбиране стандартната стратегия за съвпадение изисква всички свойства на източника и местоназначението да бъдат съчетани в произволен ред. Това е идеално за нашия сценарий .

2.2. Въведете Token

ModelMapper използва TypeToken за картографиране на общи типове. За да разберем защо е необходимо това, нека видим какво се случва, когато съпоставим списък с цели числа към списък с символи :

List integers = new ArrayList(); integers.add(1); integers.add(2); integers.add(3); List characters = new ArrayList(); modelMapper.map(integers, characters);

Освен това, ако разпечатаме елементите от списъка с символи , ще видим празен списък. Това се дължи на появата на изтриване на типа по време на изпълнение.

Ако променим нашето извикване на карта, за да използваме TypeToken , обаче, можем да създадем литерал на типа за List :

List characters = modelMapper.map(integers, new TypeToken
    
     () {}.getType());
    

По време на компилация анонимният вътрешен регистър TokenType запазва типа параметър Списък и този път преобразуването ни е успешно.

3. Използване на картографиране по избор

Списъците в Java могат да се картографират, като се използват персонализирани типове елементи.

Да приемем например, че искаме да съпоставим списък от потребителски обекти със списък UserDTO . За да постигнем това, ще извикаме map за всеки елемент:

List dtos = users .stream() .map(user -> modelMapper.map(user, UserDTO.class)) .collect(Collectors.toList());

Разбира се, с още малко работа, бихме могли да направим параметризиран метод с общо предназначение:

 List mapList(List source, Class targetClass) { return source .stream() .map(element -> modelMapper.map(element, targetClass)) .collect(Collectors.toList()); }

И така, вместо това можем да направим:

List userDtoList = mapList(users, UserDTO.class);

4. Тип карта и картографиране на свойства

Към модела User-UserDTO могат да се добавят специфични свойства като списъци или набори . TypeMap предоставя метод за изрично дефиниране на картографирането на тези свойства. Обектът TypeMap съхранява информация за картографиране на конкретни типове (класове):

TypeMap typeMap = modelMapper.createTypeMap(UserList.class, UserListDTO.class);

Класът UserList съдържа колекция от потребителски s. Тук искаме да съпоставим списъка с потребителски имена от тази колекция към списъка със свойства на класа UserListDTO . За да постигнем това, ще създадем първия клас UsersListConverter и ще го предадем List и List като типове параметри за преобразуване:

public class UsersListConverter extends AbstractConverter
    
      { @Override protected List convert(List users) { return users .stream() .map(User::getUsername) .collect(Collectors.toList()); } }
    

От създадения обект TypeMap изрично добавяме Map Mapping чрез извикване на екземпляр на клас UsersListConverter :

 typeMap.addMappings(mapper -> mapper.using(new UsersListConverter()) .map(UserList::getUsers, UserListDTO::setUsernames));

Вътре в метода addMappings , преобразуване на изрази ни позволява да дефинираме свойствата на източника към местоназначението с ламбда изрази. И накрая, той преобразува списъка с потребители в получения списък с потребителски имена.

5. Заключение

В този урок обяснихме как списъците се картографират чрез манипулиране на родови типове в ModelMapper . Можем да използваме TypeToken, генериране на родови типове и картографиране на свойстваза създаване на типове списъци с обекти и извършване на сложни картографирания

Пълният изходен код за тази статия е достъпен в GitHub.