Обзор Java — Master MapStruct: 8 случаев изучения эффективного и быстрого сопоставления объектов Java
Обзор Java — Master MapStruct: 8 случаев изучения эффективного и быстрого сопоставления объектов Java
Каталог статей
  • Обязательно посмотрите для начала
  • Обзор
    • Ключевые особенности MapStruct
    • Как работает MapStruct
    • Как использовать MapStruct
    • Преимущества и недостатки MapStruct
  • Code
    • POM
    • Тестовый пример 1: базовое картографирование
    • Тестовый пример 2: сложное сопоставление типов
    • Тестовый пример 3. Использование выражений Java
    • Тестовый пример 4. Использование пользовательских методов
    • Тестовый пример 5. Сопоставление коллекций
    • Тестовый пример 6. Использование внедрения зависимостей
    • Тестовый пример 7. Обновление существующего объекта
    • Тестовый пример 8. Сопоставление нескольких источников
  • Performance of Java Mapping Frameworks

Обязательно посмотрите для начала


Обзор

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

Ключевые особенности MapStruct
  1. безопасность типа:MapStructсуществоватькомпилировать Проверьте правила сопоставления, когда,обеспечить источникобъекти целиобъект Сопоставление атрибутов междубезопасность тип. Это уменьшает проблемы во время выполнения, вызванные ошибками преобразования типов.
  2. производительность:Сгенерированный код сопоставления использует простойgettersиsetters,Избегайте использования отражения,Тем самым обеспечивая лучшую производительность во время выполнения.
  3. Легко понять и использовать:MapStructСгенерированный код прост и понятен.,Разработчики могут легко прочитать и понять логику сопоставления.
  4. Пользовательское сопоставление:MapStructПозволяет разработчикам определять сложные правила сопоставления,Включает функции глубокого копирования и пользовательского преобразования.
  5. Ошибки выявлены заранее:компилироватьпотенциал может быть обнаружен время от временисуществоватьошибка,Если сопоставление неполное или метод сопоставления неверен,Это позволяет заранее устранить проблемы.,Избегайте сбоев во время выполнения.
Как работает MapStruct

MapStruct основан на спецификации Java JSR 269, которая позволяет обрабатывать аннотации во время компиляции. MapStruct считывает интерфейс сопоставления во время компиляции через определенный процессор аннотаций и генерирует соответствующий класс реализации. Во время этого процесса он анализирует методы сопоставления, объявленные в интерфейсе, и создает соответствующие вызовы методов получения и установки.

Как использовать MapStruct
  1. Добавить зависимости:первый,Добавьте зависимость MapStruct в файл конфигурации сборки проекта (например, Maven или Gradle).
  2. Определить интерфейс сопоставления:определитьинтерфейс,использовать@Mapperаннотация,Объявите методы, которые необходимо сопоставить.
  3. Напишите правила сопоставления:существоватькартографированиеинтерфейссередина,использовать@Mappingаннотация指定属性картографирование规则。
  4. Скомпилировать код:компилироватьвремя проекта,Процессор аннотаций MapStruct генерирует классы реализации на основе определенных правил сопоставления.
  5. Использовать картограф:существоватькодсередина,проходитьMappers.getMapper()Метод получения экземпляра картографа,и вызовите метод сопоставления.
Преимущества и недостатки MapStruct

преимущество

  • Сопоставление предусмотрено для типа безопасности,Уменьшение ошибок во время выполнения.
  • Сгенерированный код выполняется эффективно, поскольку отражения избегаются.
  • Глубокое копирование может быть достигнуто для сохранения независимости между объектами.
  • Удобство для поэтапной разработки: каждое сопоставление можно протестировать и протестировать индивидуально.
  • Легко понять, что снижает необходимость писать и поддерживать много шаблонного кода.

недостаток

  • Необходимо определить интерфейс или абстрактный класс,Это может в некоторой степени увеличить сложность кода.
  • Для сложной логики сопоставления вам может потребоваться написать собственную функцию сопоставления.
  • Если в проекте крайне высокие требования к производительности,Возможно, вы захотите оптимизировать сгенерированный код вручную.

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


Code


POM

Язык кода:javascript
копировать
  <dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct</artifactId>
        <version>${org.mapstruct.version}</version>
    </dependency>

    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct-processor</artifactId>
        <version>${org.mapstruct.version}</version>
        <!-- IntelliJ does not pick up the processor if it is not in the dependencies.
         There is already an open issue for IntelliJ see https://youtrack.jetbrains.com/issue/IDEA-150621
        -->
        <scope>provided</scope>
    </dependency>

Тестовый пример 1: базовое картографирование

Базовое сопоставление. Используя MapStruct, вы можете легко реализовать базовое сопоставление между двумя объектами Java Bean. Просто определите интерфейс преобразователя и используйте аннотации для указания исходного и целевого классов, и MapStruct сгенерирует класс реализации во время компиляции.

Entity

Язык кода:javascript
копировать
package com.artisan.mapstruct.entity;

import com.artisan.mapstruct.CarType;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author маленький мастер
 * @version 1.0
 * @mark: show me the code , change the world
 */

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Car {

    private String make;
    private int numberOfSeats;
    private CarType type;

}
Язык кода:javascript
копировать
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CarDto {

    private String make;
    private int seatCount;
    private String type;
}
Язык кода:javascript
копировать
package com.artisan.mapstruct;

/**
 * @author artisan
 */

public enum CarType {
    BMW(1, "BMW"),
    FLL(2, "FLL");


    private int code;
    private String brand;

    CarType(int code, String brand) {
        this.code = code;
        this.brand = brand;
    }

    public int getCode() {
        return code;
    }

    public String getBrand() {
        return brand;
    }

    // Как получить бренд на основе кода
    public static String getBrandByCode(int code) {
        for (CarType carType : CarType.values()) {
            if (carType.getCode() == code) {
                return carType.getBrand();
            }
        }
        return null; // Если код не существует, верните ноль или другое значение по умолчанию.
    }
}

Mapper

Язык кода:javascript
копировать
package com.artisan.mapstruct.entity;

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;

/**
 * @author маленький мастер
 * @version 1.0
 * @mark: show me the code , change the world
 */

@Mapper
public interface CarMapper {

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

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

Модульное тестирование

Язык кода:javascript
копировать
package com.artisan.mapstruct;

import com.artisan.bootbeanutils.BootBeanUtilsApplication;
import com.artisan.mapstruct.entity.Car;
import com.artisan.mapstruct.entity.CarDto;
import com.artisan.mapstruct.entity.CarMapper;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

/**
 * Базовое сопоставление атрибутов
 */
@SpringBootTest(classes = BootBeanUtilsApplication.class)
class MapStructApplicationTests1 {


    @Test
    public void testBasicTypeConvert() {
        Car car = new Car("artisan", 7, CarType.BMW);
        CarDto cardto = CarMapper.INSTANCE.carToCarDto(car);

        System.out.println(car);
        System.out.println(cardto);

        Assertions.assertEquals(car.getNumberOfSeats(), cardto.getSeatCount());
    }


}

Тестовый пример 2: сложное сопоставление типов

Entity

Язык кода:javascript
копировать
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Car {

    private String make;
    private int numberOfSeats;
    private CarType type;
    // Содержит объект (Включая сложные типы или пользовательские типы)
    private AnotherPojo anotherPojo;
}
Язык кода:javascript
копировать
@Data
@AllArgsConstructor
@NoArgsConstructor
public class AnotherPojo {

    private String pa;
    private long pb;
}
Язык кода:javascript
копировать
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CarDto {

    private String make;
    private int seatCount;
    private String type;

Mapper

Язык кода:javascript
копировать
package com.artisan.mapstruct.entity2;

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;

/**
 * @author маленький мастер
 * @version 1.0
 * @mark: show me the code , change the world
 */

@Mapper
public interface CarMapper {

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

    @Mapping(source = "anotherPojo.pa", target = "pa")
    @Mapping(source = "anotherPojo.pb", target = "pb")
    CarDto carToCarDto(Car car);
}

Модульное тестирование

Язык кода:javascript
копировать
package com.artisan.mapstruct;

import com.artisan.bootbeanutils.BootBeanUtilsApplication;
import com.artisan.mapstruct.entity2.Car;
import com.artisan.mapstruct.entity2.CarDto;
import com.artisan.mapstruct.entity2.CarMapper;
import com.artisan.mapstruct.entity2.AnotherPojo;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

/**
 * сложное сопоставление типов
 */
@SpringBootTest(classes = BootBeanUtilsApplication.class)
class MapStructApplicationTests2 {

    @Test
    public void testComplexConvert() {
        Car car = new Car("artisan", 7, CarType.BMW ,new AnotherPojo("paValue",66L));
        CarDto cardto = CarMapper.INSTANCE.carToCarDto(car);

        System.out.println(car);
        System.out.println(cardto);

        Assertions.assertEquals(car.getAnotherPojo().getPa() , cardto.getPa());
        Assertions.assertEquals(car.getAnotherPojo().getPb() , cardto.getPb());

    }


}

Тестовый пример 3. Использование выражений Java

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

Entity

Язык кода:javascript
копировать
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Car {

    private String make;
    private String brand;
    private int numberOfSeats;
    private CarType type;

}
Язык кода:javascript
копировать
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CarDto {

    private String make;
    private int seatCount;
    private String type;
    private String fullInfo;
}

Mapper

Язык кода:javascript
копировать
@Mapper
public interface CarMapper {

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

    // В процессе сопоставления может возникнуть необходимость использовать пользовательскую логику. Карта Структура разрешить вам использовать Java Выражение для достижения этой цели
    @Mapping(expression = "java(car.getMake() + ' ' + car.getBrand())", target = "fullInfo")
    CarDto carToCarDto(Car car);
}

Модульное тестирование

Язык кода:javascript
копировать
package com.artisan.mapstruct;

import com.artisan.bootbeanutils.BootBeanUtilsApplication;
import com.artisan.mapstruct.entity3.Car;
import com.artisan.mapstruct.entity3.CarDto;
import com.artisan.mapstruct.entity3.CarMapper;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

/**
 * Используйте выражения
 */
@SpringBootTest(classes = BootBeanUtilsApplication.class)
class MapStructApplicationTests3 {


    @Test
    public void testExpressConvert() {
        Car car = new Car("artisan", "BMW", 7, CarType.BMW);
        CarDto cardto = CarMapper.INSTANCE.carToCarDto(car);

        System.out.println(car);
        System.out.println(cardto);

        Assertions.assertEquals(car.getMake() + ' ' + car.getBrand(), cardto.getFullInfo());

    }


}

Тестовый пример 4. Использование пользовательских методов

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

Entity

Язык кода:javascript
копировать
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Car {

    private String make;
    private int numberOfSeats;
    private CarType type;

    // Заводская дата  , Тип строки
    private String manufactureDate;

}
Язык кода:javascript
копировать
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CarDto {

    private String make;
    private int seatCount;
    private String type;


    // Заводская дата  , Тип LocalDate
    private LocalDate manufactureDate2;
}

Mapper

Язык кода:javascript
копировать
package com.artisan.mapstruct.entity4;

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Named;
import org.mapstruct.factory.Mappers;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

/**
 * @author маленький мастер
 * @version 1.0
 * @mark: show me the code , change the world
 */

@Mapper
public interface CarMapper {

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

    @Mapping(source = "manufactureDate", target = "manufactureDate2", qualifiedByName = "stringToLocalDate")
    CarDto carToCarDto(Car car);


    @Named("stringToLocalDate")
    default LocalDate stringToLocalDate(String date) {
        return LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
    }

}

Это тоже нормально

Язык кода:javascript
копировать
package com.artisan.mapstruct.entity4;

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Named;
import org.mapstruct.factory.Mappers;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

/**
 * @author маленький мастер
 * @version 1.0
 * @mark: show me the code , change the world
 */

@Mapper
public interface CarMapper {

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

    @Mapping(source = "manufactureDate", target = "manufactureDate2")
    CarDto carToCarDto(Car car);


    default LocalDate stringToLocalDate(String date) {
        return LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
    }

}

Может быть реализован с использованием интерфейса Java по умолчанию.


Модульное тестирование

Язык кода:javascript
копировать
package com.artisan.mapstruct;

import com.artisan.bootbeanutils.BootBeanUtilsApplication;
import com.artisan.mapstruct.entity4.Car;
import com.artisan.mapstruct.entity4.CarDto;
import com.artisan.mapstruct.entity4.CarMapper;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

/**
 * Использовать собственный метод
 *
 * В некоторых случаях может потребоваться Пользовательское парламентская логика. Этого можно добиться, определив собственный метод в интерфейсе картографа.
 */
@SpringBootTest(classes = BootBeanUtilsApplication.class)
class MapStructApplicationTests4 {


    @Test
    public void testCustomConvert() {
        Car car = new Car("artisan",   7, CarType.BMW, "2099-12-12");
        CarDto cardto = CarMapper.INSTANCE.carToCarDto(car);

        System.out.println(car);
        System.out.println(cardto);

        Assertions.assertEquals(car.getManufactureDate(), cardto.getManufactureDate2().toString());

    }


}

Тестовый пример 5. Сопоставление коллекций

Entity

Язык кода:javascript
копировать
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Car {

    private String make;
    private int numberOfSeats;
    private CarType type;

}
Язык кода:javascript
копировать
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CarDto {

    private String make;
    private int numberOfSeats;
    private String type;
}

Mapper

Язык кода:javascript
копировать
package com.artisan.mapstruct.entity5;

import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;

import java.util.List;

/**
 * @author маленький мастер
 * @version 1.0
 * @mark: show me the code , change the world
 */

@Mapper
public interface CarMapper {

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

    List<CarDto> carsToCarDtos(List<Car> cars);
}

Модульное тестирование

Язык кода:javascript
копировать
package com.artisan.mapstruct;

import com.artisan.bootbeanutils.BootBeanUtilsApplication;
import com.artisan.mapstruct.entity5.Car;
import com.artisan.mapstruct.entity5.CarDto;
import com.artisan.mapstruct.entity5.CarMapper;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.ArrayList;
import java.util.List;

/**
 * коллекция карт
 */
@SpringBootTest(classes = BootBeanUtilsApplication.class)
class MapStructApplicationTests5 {


    @Test
    public void testCollectionfConvert() {
        Car car = new Car("artisan", 7, CarType.BMW);
        Car car2 = new Car("artisan2", 9, CarType.FLL);

        List carList = new ArrayList();
        carList.add(car);
        carList.add(car2);

        List<CarDto> cardtos = CarMapper.INSTANCE.carsToCarDtos(carList);
        cardtos.stream().forEach(System.out::println);
    }
}

Тестовый пример 6. Использование внедрения зависимостей

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

Entity

Язык кода:javascript
копировать
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Car {

    private String make;
    private int numberOfSeats;
    private CarType type;

}
Язык кода:javascript
копировать
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CarDto {

    private String make;
    private int seatCount;
    private String type;
}

Mapper

componentModel = MappingConstants.ComponentModel.SPRING

Язык кода:javascript
копировать
package com.artisan.bootbeanutils.controller.ms;

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingConstants;
import org.mapstruct.factory.Mappers;

/**
 * @author маленький мастер
 * @version 1.0
 * @mark: show me the code , change the world
 */

@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
public interface CarMapper {

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

Модульное тестирование

Язык кода:javascript
копировать
package com.artisan.bootbeanutils.controller;

import com.artisan.bootbeanutils.controller.ms.Car;
import com.artisan.bootbeanutils.controller.ms.CarDto;
import com.artisan.bootbeanutils.controller.ms.CarMapper;
import com.artisan.bootbeanutils.controller.ms.CarType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author маленький мастер
 * @version 1.0
 * @mark: show me the code , change the world
 */

@RestController
public class TestController {

    @Autowired
    private CarMapper carMapper;

    @GetMapping("/test")
    public String test() {
        CarDto carDto = carMapper.carToCarDto(new Car("artisan", 8, CarType.BMW));
        return carDto.toString();
    }
}

автоматический впрыск CarMapper


Тестовый пример 7. Обновление существующего объекта

Entity

Язык кода:javascript
копировать
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Car {

    private String make;
    private int numberOfSeats;
    private CarType type;

}
Язык кода:javascript
копировать
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CarDto {

    private String make;
    private int seatCount;
    private String type;
}

Mapper

Язык кода:javascript
копировать
package com.artisan.mapstruct.entity7;

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
import org.mapstruct.factory.Mappers;

/**
 * @author маленький мастер
 * @version 1.0
 * @mark: show me the code , change the world
 */

@Mapper
public interface CarMapper {

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


    @Mapping(source = "seatCount", target = "numberOfSeats")
    void updateCarFromDTO(CarDto personDto, @MappingTarget Car car);
}

Модульное тестирование

Язык кода:javascript
копировать
package com.artisan.mapstruct;

import com.artisan.bootbeanutils.BootBeanUtilsApplication;
import com.artisan.mapstruct.entity7.Car;
import com.artisan.mapstruct.entity7.CarDto;
import com.artisan.mapstruct.entity7.CarMapper;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

/**
 * MapStruct Также может использоваться для обновления существующего объекта вместо создания нового.
 */
@SpringBootTest(classes = BootBeanUtilsApplication.class)
class MapStructApplicationTests7 {


    @Test
    public void testUpdate() {

        // Имитировать существование автомобильного объекта
        Car car = new Car("artisan", 9, CarType.BMW);


        CarDto carDto = new CarDto("artisanDto", 100, CarType.FLL.getBrand());

        // Используется для обновления существующего объекта вместо создания нового.
        CarMapper.INSTANCE.updateCarFromDTO(carDto, car);


        System.out.println(carDto);
        System.out.println(car);

    }


}

Тестовый пример 8. Сопоставление нескольких источников

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

Entity

Язык кода:javascript
копировать
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Car {

    private String make;
    private int numberOfSeats;
    private CarType type;

}
Язык кода:javascript
копировать
@Data
@NoArgsConstructor
@AllArgsConstructor
public class AnotherPojo {

    private String pa;
}
Язык кода:javascript
копировать
package com.artisan.mapstruct.entity8;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author маленький мастер
 * @version 1.0
 * @mark: show me the code , change the world
 */

@Data
@AllArgsConstructor
@NoArgsConstructor
public class CarDto {

    private String make;
    private int seatCount;
    private String type;
    private String pa;
}

Mapper

Язык кода:javascript
копировать
package com.artisan.mapstruct.entity8;

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;

/**
 * @author маленький мастер
 * @version 1.0
 * @mark: show me the code , change the world
 */

@Mapper
public interface CarMapper {

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

    @Mapping(source = "car.numberOfSeats", target = "seatCount")
    @Mapping(source = "anotherPojo.pa", target = "pa")
    CarDto carToCarDto(Car car, AnotherPojo anotherPojo);
}

Модульное тестирование

Язык кода:javascript
копировать
package com.artisan.mapstruct;

import com.artisan.bootbeanutils.BootBeanUtilsApplication;
import com.artisan.mapstruct.entity8.AnotherPojo;
import com.artisan.mapstruct.entity8.Car;
import com.artisan.mapstruct.entity8.CarDto;
import com.artisan.mapstruct.entity8.CarMapper;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

/**
 * картографирование с несколькими источниками
 * <p>
 * Может сопоставлять объект из нескольких источников с одним целевым объектом.
 */
@SpringBootTest(classes = BootBeanUtilsApplication.class)
class MapStructApplicationTests8 {


    @Test
    public void MultiSourceConvert() {

        Car car = new Car("artisan", 7, CarType.BMW);
        AnotherPojo anotherPojo = new AnotherPojo("paValue");

        CarDto cardto = CarMapper.INSTANCE.carToCarDto(car, anotherPojo);

        System.out.println(car);
        System.out.println(cardto);

        Assertions.assertEquals(car.getNumberOfSeats(), cardto.getSeatCount());
        Assertions.assertEquals(anotherPojo.getPa(), cardto.getPa());

    }


}

Конечно, вы также можете нажать здесь: Quick Guide to MapStruct Есть несколько примеров, которые не описаны, зайдите и посмотрите.


Performance of Java Mapping Frameworks

Performance of Java Mapping Frameworks

https://github.com/eugenp/tutorials/tree/master/performance-tests

boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose