Всем привет ,

Сегодня мы подробно рассмотрим упрощение сопоставления объектов в Java с помощью MapStruct.

Что такое MapStruct?

MapStruct — это генератор кода, который значительно упрощает реализацию сопоставлений между типами Java-бинов на основе соглашения, а не подхода к конфигурации.

Сгенерированный код сопоставления использует простые вызовы методов и поэтому является быстрым, типобезопасным и простым для понимания.

MapStruct — это процессор аннотаций Java для создания безопасных по типу классов сопоставления bean-компонентов. Это позволяет разработчикам определять сопоставления между классами Java с помощью простых и интуитивно понятных аннотаций, уменьшая объем шаблонного кода, который необходимо написать. Это проект с открытым исходным кодом, который активно поддерживается командой разработчиков.

Зачем нам нужен MapStruct?
Многоуровневые приложения часто требуют сопоставления между различными объектными моделями (например, сущностями и DTO). Написание такого кода сопоставления — утомительная и подверженная ошибкам задача. MapStruct стремится упростить эту работу, максимально автоматизировав ее.

В отличие от других картографических фреймворков, MapStruct генерирует сопоставления bean-компонентов во время компиляции, что обеспечивает высокую производительность, позволяет быстро получать обратную связь от разработчиков и проводить тщательную проверку ошибок.

Возможности MapStruct:

  1. MapStruct также может генерировать сопоставления для вложенных классов, коллекций и сопоставлений и поддерживает сопоставление пользовательских типов с помощью настраиваемых преобразователей.
  2. В дополнение к своим базовым функциям MapStruct также предоставляет расширенные функции, такие как возможность настройки сгенерированного кода сопоставления с использованием методов шаблона, возможность использования существующих методов сопоставления как части сгенерированного кода и возможность сопоставления между свойствами компонента с различными имена.
  3. MapStruct также поддерживает сопоставление между различными классами Java Bean с разными именами свойств и даже может генерировать преобразователи, которые обрабатывают нулевые значения.
  4. MapStruct также обладает широкими возможностями настройки и настройки, что позволяет разработчикам определять свои собственные соглашения об именах, настраивать поведение методов сопоставления и даже определять свои собственные методы сопоставления.
  5. MapStruct также позволяет использовать Spring, CDI и другие среды внедрения зависимостей для управления жизненным циклом преобразователя и внедрения зависимостей в методы сопоставления.
  6. MapStruct можно интегрировать с популярными инструментами сборки, такими как Maven и Gradle, что упрощает использование в существующих проектах Java. Он также хорошо работает с другими библиотеками и средами Java, такими как Spring и Hibernate.
  7. Еще одним преимуществом MapStruct является его высокая производительность, поскольку сгенерированный код отображения представляет собой простой Java и не зависит от отражения или прокси-серверов времени выполнения. Это означает, что сопоставления, созданные с помощью MapStruct, выполняются так же быстро, как и сопоставления, написанные от руки, а во многих случаях даже быстрее.
  8. MapStruct также поддерживает создание неизменяемых целей сопоставления, которые могут быть полезны в контекстах функционального программирования, а также могут улучшить потокобезопасность созданных преобразователей.
  9. MapStruct также предоставляет возможность проверки конфигурации сопоставления во время компиляции с помощью аннотации @Mapping(target = «‹method›»), что может помочь обнаружить проблемы на раннем этапе и избежать ошибок во время выполнения.
  10. MapStruct поддерживает отображение между различными типами данных, не только между Java Beans, но и между другими типами данных, такими как примитивные типы, массивы и перечисления. Кроме того, он также поддерживает сопоставление между различными источниками данных, такими как объекты JPA, DTO и объекты JSON.
  11. MapStruct также обеспечивает встроенную поддержку сопоставления между сущностями JPA и DTO, что позволяет легко интегрироваться с платформами сохраняемости на основе JPA, такими как Hibernate.
  12. Еще одной особенностью MapStruct является поддержка инкрементной компиляции, что означает, что он создает реализации преобразователя только для типов, которые изменились с момента последней компиляции. Это может значительно сократить время сборки проектов с большим количеством картографов и сделать процесс разработки более эффективным.
  13. MapStruct также позволяет использовать внешние библиотеки, такие как ModelMapper, Dozer и Selma, в сгенерированных реализациях картографа, что может быть полезно в сценариях, когда эти библиотеки предоставляют функции, которые MapStruct изначально не поддерживает.
  14. MapStruct также обеспечивает встроенную поддержку сопоставления между сущностями JPA и DTO, что позволяет легко интегрироваться с платформами сохраняемости на основе JPA, такими как Hibernate. Это может быть особенно полезно в приложениях, использующих JPA в качестве основного уровня доступа к данным, поскольку позволяет разделить модель предметной области и объекты передачи данных.

Как интегрировать MapStruct?
MapStruct — это процессор аннотаций, который подключается к компилятору Java и может использоваться в сборках командной строки (Maven, Gradle и т. д.), а также из вашего предпочтительная среда IDE.
MapStruct использует разумные значения по умолчанию, но делает все возможное, когда дело доходит до настройки или реализации специального поведения.

Реализация MapStruct

Давайте сделаем упражнение для рук. Мы реализуем сопоставитель MapStruct в проекте Java Spring Boot:

  1. Добавьте зависимость MapStruct в файл pom.xml вашего проекта:
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-jdk8</artifactId>
    <version>1.5.3.Final</version>
</dependency>

2. Создайте интерфейс преобразователя, определяющий методы сопоставления. Например, предположим, что у нас есть сущность Person и класс PersonDTO, между которыми мы хотим сопоставить. Мы можем создать интерфейс PersonMapper следующим образом:

@Mapper
public interface PersonMapper {
    PersonMapper INSTANCE = Mappers.getMapper( PersonMapper.class );
PersonDTO toDTO(Person person);
    Person toEntity(PersonDTO personDTO);
}

3. Аннотируйте методы сопоставления соответствующими аннотациями @Mapping и @Mappings. Например:

@Mapper
public interface PersonMapper {
    PersonMapper INSTANCE = Mappers.getMapper( PersonMapper.class );
@Mapping(target = "id", source = "personId")
    @Mapping(target = "name", source = "personName")
    PersonDTO toDTO(Person person);
    @InheritInverseConfiguration
    Person toEntity(PersonDTO personDTO);
}

4. В своем классе обслуживания вы можете использовать картограф следующим образом:

@Service
public class PersonService {
    public PersonDTO getPersonDTO(Person person) {
        return PersonMapper.INSTANCE.toDTO(person);
    }
public Person getPersonEntity(PersonDTO personDTO) {
        return PersonMapper.INSTANCE.toEntity(personDTO);
    }
}

5. Добавьте следующее в ваши application.properties

mapstruct.defaultComponentModel=spring

6. Наконец, вам нужно настроить приложение Spring для сканирования пакета, содержащего ваши интерфейсы картографа, и для использования обработчика аннотаций MapStruct. Вы можете сделать это, добавив следующее в свой класс @Configuration:

@Configuration
@ComponentScan(basePackages = "com.example.mapper")
@EnableMapStruct
public class MyConfiguration {
}

Это базовый пример использования MapStruct в проекте Spring. В зависимости от ваших конкретных требований вам может потребоваться настроить методы сопоставления или конфигурацию картографа. Вы можете найти более подробную документацию и примеры на веб-сайте MapStruct.



Плюсы и минусы MapStruct

Плюсы MapStruct:

  1. Типобезопасность: MapStruct генерирует типобезопасный код сопоставления, что снижает вероятность ошибок во время выполнения.
  2. На основе аннотаций: MapStruct использует простые и интуитивно понятные аннотации, что сокращает объем стандартного кода, который необходимо написать.
  3. Высокая производительность: сгенерированный код сопоставления представляет собой простой Java и не зависит от отражения или прокси-серверов времени выполнения, что делает его быстрым и эффективным.
  4. Настраиваемость: MapStruct обладает широкими возможностями настройки и настройки, что позволяет разработчикам определять свои собственные соглашения об именах, настраивать поведение методов сопоставления и даже определять свои собственные настраиваемые методы сопоставления.
  5. Интеграция: MapStruct можно интегрировать с популярными инструментами сборки, такими как Maven и Gradle, и он хорошо работает с другими библиотеками и средами Java, такими как Spring и Hibernate.
  6. Инкрементная компиляция: MapStruct допускает инкрементную компиляцию, что может значительно сократить время сборки проектов с большим количеством картографов.
  7. Поддержка внешних библиотек: MapStruct позволяет использовать внешние библиотеки, такие как ModelMapper, Dozer и Selma, в сгенерированных реализациях картографа.
  8. Хорошая поддержка сообщества: за MapStruct стоит большое сообщество, многие разработчики вносят свой вклад в проект и предоставляют примеры и решения для распространенных проблем.

Минусы MapStruct:

  1. Кривая обучения: для эффективного использования MapStruct требуется определенный уровень знаний и опыта.
  2. Не подходит для всех вариантов использования: MapStruct может не подходить для всех случаев использования и может не предоставлять все функции, которые нужны некоторым разработчикам.
  3. Большие проекты: В некоторых случаях проекты с большим количеством картографов могут привести к значительному увеличению размера генерируемого кода.
  4. Ограниченная поддержка сторонних библиотек: MapStruct может не поддерживать все сторонние библиотеки и фреймворки, что ограничивает его гибкость.
  5. Требуется Java 8 или более поздняя версия: MapStruct требует Java 8 или более поздней версии для запуска и использования.

Управление зависимостью MapStruct

Кроме того, вы также можете настроить MapStruct для использования встроенного в Spring механизма внедрения зависимостей для управления жизненным циклом преобразователя и внедрения зависимостей в методы сопоставления. Вот пример того, как это сделать:

  1. В интерфейсе вашего картографа вы можете использовать аннотацию @Autowired для внедрения зависимостей в методы сопоставления. Например:
@Mapper
public interface PersonMapper {
@Autowired
    PersonRepository personRepository;
    @Mapping(target = "id", source = "personId")
    @Mapping(target = "name", source = "personName")
    PersonDTO toDTO(Person person);
    @InheritInverseConfiguration
    Person toEntity(PersonDTO personDTO);
}

2. Чтобы Spring мог управлять жизненным циклом преобразователя, вы можете создать @Bean в своем классе @Configuration, который возвращает экземпляр преобразователя. Например:

@Configuration
@ComponentScan(basePackages = "com.example.mapper")
@EnableMapStruct
public class MyConfiguration {
@Bean
    public PersonMapper personMapper() {
        return Mappers.getMapper(PersonMapper.class);
    }
}

3. Таким образом, вы можете использовать аннотацию @Autowired в своем классе обслуживания для внедрения картографа, например:

@Service
public class PersonService {
@Autowired
    private PersonMapper personMapper;
    public PersonDTO getPersonDTO(Person person) {
        return personMapper.toDTO(person);
    }
    public Person getPersonEntity(PersonDTO personDTO) {
        return personMapper.toEntity(personDTO);
    }
}

Используя этот подход, вы можете использовать встроенный в Spring механизм внедрения зависимостей для управления жизненным циклом преобразователя и внедрения зависимостей в методы сопоставления. Это может сделать ваш код более удобным для сопровождения и тестирования, а также может упростить управление зависимостями между различными компонентами в вашем приложении.

Поддержка Ломбока

MapStruct поддерживает сопоставление между классами, использующими библиотеку Lombok. Lombok — это библиотека Java, предоставляющая набор аннотаций, которые можно использовать для создания шаблонного кода, например геттеры, сеттеры и конструкторы.

При сопоставлении между классами, использующими Lombok, MapStruct может автоматически обнаруживать и использовать сгенерированные методы и конструкторы, не требуя от вас написания явных методов сопоставления. Это может сделать интерфейсы картографа более лаконичными и читабельными, а также уменьшить объем шаблонного кода, который необходимо написать.

Чтобы использовать Lombok с MapStruct, вам необходимо включить зависимость Lombok в свой проект и настроить инструмент сборки для использования обработчика аннотаций Lombok. Вот пример того, как это сделать в проекте Maven:

  1. Добавьте зависимость Lombok в файл pom.xml вашего проекта:
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.24</version>
</dependency>

2. Добавьте плагин Lombok в раздел сборки вашего проекта в файле pom.xml:

<build>
    <plugins>
        <plugin>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok-maven-plugin</artifactId>
            <version>1.18.20.0</version>
            <executions>
                <execution>
                    <goals>
                        <goal>delombok</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>


3. Наконец, вам нужно аннотировать свои классы соответствующими аннотациями Ломбока, такими как @Getter, @Setter и @NoArgsConstructor. Например:

@Getter
@Setter
@NoArgsConstructor
public class Person {
    private Long id;
    private String name;
}

При такой настройке MapStruct может автоматически обнаруживать и использовать сгенерированные геттеры и сеттеры при сопоставлении между классами, что может сделать интерфейсы преобразователя более краткими и удобочитаемыми.

MapStruct и Lombok: важные моменты, которые следует учитывать

  1. Также стоит отметить, что если вы используете аннотацию Lombok @Data, MapStruct будет использовать сгенерированные методы для выполнения сопоставления.
  2. Однако если вы используете аннотацию @Value, MapStruct не сможет выполнить сопоставление, так как эта аннотация создает неизменяемый класс с конечными полями и без сеттеров.
  3. Кроме того, MapStruct также поддерживает использование функциональных интерфейсов Java 8 и лямбда-выражений в методах сопоставления, что может сделать реализацию преобразователя более лаконичной и читабельной.
  4. MapStruct можно интегрировать с другими библиотеками и платформами, такими как Spring, что упрощает его использование в существующих проектах, а также позволяет внедрять зависимости в методы сопоставления.
  5. MapStruct — это мощный и эффективный инструмент для упрощения процесса сопоставления между компонентами Java и другими типами данных, с широким набором функций и хорошей интеграцией с другими библиотеками и фреймворками. Это может значительно улучшить ремонтопригодность и читабельность кода Java, делая процесс разработки более эффективным.
  6. За MapStruct стоит большое сообщество, многие разработчики вносят свой вклад в проект и предоставляют примеры и решения для распространенных проблем. Это делает его хорошо документированным и поддерживаемым инструментом, что позволяет разработчикам легко находить помощь в случае необходимости.
  7. Еще одна вещь, о которой стоит упомянуть, это то, что если вы используете аннотацию Lombok @Builder в своем классе, MapStruct будет использовать методы построителя для создания экземпляров целевого класса в процессе сопоставления. Это может быть полезно в сценариях, когда вы хотите создать экземпляр целевого класса с определенными значениями для некоторых его свойств, оставив другие неинициализированными.
  8. Кроме того, при отображении между классами, использующими Lombok, вы должны знать, что методы Lombok equals и hashCode могут быть сгенерированы неправильно, если класс, который вы пытаетесь отобразить, имеет поля, которые не относятся к примитивному типу, это может вызывать проблемы при использовании картографа в определенных ситуациях. Чтобы избежать этого, вы можете использовать аннотацию Lombok @EqualsAndHashCode, чтобы вручную указать, какие поля следует использовать для генерации методов equals и hashCode.
  9. Также стоит отметить, что если вы используете аннотации Lombok @Log и @Slf4j для создания регистраторов, вы должны включить необходимые зависимости для log4j или slf4j и соответствующим образом настроить свой проект.
  10. Наконец, стоит отметить, что MapStruct использует методы Lombok @Getter и @Setter, но не генерирует их, если они не существуют. Это означает, что если вы аннотируете свой класс с помощью @Getter и @Setter, но забудете включить библиотеку Lombok, ваш код все равно скомпилируется, но сопоставление не будет работать.

В заключение, MapStruct и Lombok — это два мощных инструмента, которые можно использовать вместе для улучшения удобства сопровождения и читабельности кода Java.

Поддержка MapStruct для Lombok позволяет разработчикам определять сопоставления между классами Java с помощью простых и интуитивно понятных аннотаций, уменьшая объем шаблонного кода, который необходимо написать, а Lombok можно использовать для создания стандартного кода, такого как геттеры, сеттеры и конструкторы, которые могут сделать код более лаконичен.

Мы надеемся, что вам понравился этот пост об упрощении сопоставления объектов в Java с помощью MapStruct.

Счастливого обучения… Счастливого кодирования…..

Другие интересные статьи:



АРМ Лямбда в действии

AWS SOAR: Повышение безопасности с помощью автоматизации

Java: Понимание золотой пайки Phi

Обучение AWS: путь к безграничным возможностям в облаке.

Бесплатные способы изучения облака AWS во время праздников

Понимание 𝗻𝗴

Команды Linux для облачного обучения

Принципы программирования на Java: Закон Деметры