### Quick Start Test Example Source: https://github.com/linpeilie/mapstruct-plus/blob/main/README.md Demonstrates converting between User and UserDto objects using the injected Converter instance. Asserts the correctness of the conversion in both directions. ```java @SpringBootTest public class QuickStartTest { @Autowired private Converter converter; @Test public void test() { User user = new User(); user.setUsername("jack"); user.setAge(23); user.setYoung(false); UserDto userDto = converter.convert(user, UserDto.class); System.out.println(userDto); // UserDto{username='jack', age=23, young=false} assert user.getUsername().equals(userDto.getUsername()); assert user.getAge() == userDto.getAge(); assert user.isYoung() == userDto.isYoung(); User newUser = converter.convert(userDto, User.class); System.out.println(newUser); // User{username='jack', age=23, young=false} assert user.getUsername().equals(newUser.getUsername()); assert user.getAge() == newUser.getAge(); assert user.isYoung() == newUser.isYoung(); } } ``` -------------------------------- ### Accessing Mapper Instance via INSTANCE Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/mapstruct/1-5-5-Final.md Provides an example of how to use the singleton INSTANCE property to call mapping methods on a mapper. ```java Car car = ...; CarDto dto = CarMapper.INSTANCE.carToCarDto( car ); ``` -------------------------------- ### Define Source and Target Models Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/guide/class-convert.md Example models Car and CarDto annotated with @AutoMapper. ```java @AutoMapper(target = CarDto.class) @Data public class Car { private Tyre tyre; } ``` ```java @Data public class CarDto { private TyreDTO tyre; } ``` -------------------------------- ### Map From Multiple Source Parameters with Direct Reference Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/mapstruct/1-5-5-Final.md Map properties directly from source parameters, including non-bean types. This example maps an Integer 'hn' to the 'houseNumber' property. ```java @Mapper public interface AddressMapper { @Mapping(target = "description", source = "person.description") @Mapping(target = "houseNumber", source = "hn") DeliveryAddressDto personAndAddressToDeliveryAddressDto(Person person, Integer hn); } ``` -------------------------------- ### Solon Object Mapping Test Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/en/introduction/quick-start.md Tests object mapping from User to UserDto and back using MapStruct Plus within a Solon application context. Requires Solon test setup. ```java @SolonTest(DemoApp.class) @ExtendWith(SolonJUnit5Extension.class) public class QuickStartTest { @Inject private Converter converter; @Test public void test() { User user = new User(); user.setUsername("jack"); user.setAge(23); user.setYoung(false); UserDto userDto = converter.convert(user, UserDto.class); System.out.println(userDto); // UserDto{username='jack', age=23, young=false} assert user.getUsername().equals(userDto.getUsername()); assert user.getAge() == userDto.getAge(); assert user.isYoung() == userDto.isYoung(); User newUser = converter.convert(userDto, User.class); System.out.println(newUser); // User{username='jack', age=23, young=false} assert user.getUsername().equals(newUser.getUsername()); assert user.getAge() == newUser.getAge(); assert user.isYoung() == newUser.isYoung(); } } ``` -------------------------------- ### Define Bidirectional Data Structures Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/en/guide/cycle-avoiding.md Example of source and target classes with bidirectional references that would cause stack overflow during standard conversion. ```java @Data public class TreeNode { private TreeNode parent; private List children; } @Data public class TreeNodeDto { private TreeNodeDto parent; private List children; } ``` -------------------------------- ### MapStruct Generated CarMapper Implementation Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/mapstruct/1-5-5-Final.md This is an example of a MapStruct-generated implementation class for the CarMapper interface. It shows how MapStruct translates mapping definitions into concrete code, handling nested object mapping and type conversions. ```java // GENERATED CODE public class CarMapperImpl implements CarMapper { @Override public CarDto carToCarDto(Car car) { if ( car == null ) { return null; } CarDto carDto = new CarDto(); if ( car.getFeatures() != null ) { carDto.setFeatures( new ArrayList( car.getFeatures() ) ); } carDto.setManufacturer( car.getMake() ); carDto.setSeatCount( car.getNumberOfSeats() ); carDto.setDriver( personToPersonDto( car.getDriver() ) ); carDto.setPrice( String.valueOf( car.getPrice() ) ); if ( car.getCategory() != null ) { carDto.setCategory( car.getCategory().toString() ); } carDto.setEngine( engineToEngineDto( car.getEngine() ) ); return carDto; } @Override public PersonDto personToPersonDto(Person person) { //... } private EngineDto engineToEngineDto(Engine engine) { if ( engine == null ) { return null; } EngineDto engineDto = new EngineDto(); engineDto.setHorsePower(engine.getHorsePower()); engineDto.setFuel(engine.getFuel()); return engineDto; } } ``` -------------------------------- ### Custom Type Converter Implementation Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/en/guide/class-convert.md Define a custom type converter as a Spring Bean to handle specific type conversions. This example converts a comma-separated string to a List of strings. ```java @Component public class StringToListString { public List stringToListString(String str) { return StrUtil.split(str); } } ``` -------------------------------- ### Spring Boot Object Mapping Test Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/en/introduction/quick-start.md Tests object mapping from User to UserDto and back using MapStruct Plus in a Spring Boot environment. Requires Spring Boot test setup. ```java import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest public class QuickStartTest { @Autowired private Converter converter; @Test public void test() { User user = new User(); user.setUsername("jack"); user.setAge(23); user.setYoung(false); UserDto userDto = converter.convert(user, UserDto.class); System.out.println(userDto); // UserDto{username='jack', age=23, young=false} assert user.getUsername().equals(userDto.getUsername()); assert user.getAge() == userDto.getAge(); assert user.isYoung() == userDto.isYoung(); User newUser = converter.convert(userDto, User.class); System.out.println(newUser); // User{username='jack', age=23, young=false} assert user.getUsername().equals(newUser.getUsername()); assert user.getAge() == newUser.getAge(); assert user.isYoung() == newUser.isYoung(); } } ``` -------------------------------- ### Configure Gradle for SpringBoot Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/en/introduction/install.md Include the mapstruct-plus-spring-boot-starter and annotation processor dependencies. ```groovy dependencies { implementation 'io.github.linpeilie:mapstruct-plus-spring-boot-starter:latest version' annotationProcessor 'io.github.linpeilie:mapstruct-plus-processor:latest version' } ``` -------------------------------- ### Configure Maven for SpringBoot Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/en/introduction/install.md Use the mapstruct-plus-spring-boot-starter dependency and configure the annotation processor path. ```xml latest version io.github.linpeilie mapstruct-plus-spring-boot-starter ${mapstruct-plus.version} org.apache.maven.plugins maven-compiler-plugin 3.8.1 1.8 1.8 io.github.linpeilie mapstruct-plus-processor ${mapstruct-plus.version} ``` -------------------------------- ### Test Object Mapping with Solon Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/introduction/quick-start.md Demonstrates how to use MapStruct-Plus for object mapping within a Solon test environment. It covers converting between User and UserDto objects and verifies the mapping. ```java @SolonTest(DemoApp.class) @ExtendWith(SolonJUnit5Extension.class) public class QuickStartTest { @Inject private Converter converter; @Test public void test() { User user = new User(); user.setUsername("jack"); user.setAge(23); user.setYoung(false); UserDto userDto = converter.convert(user, UserDto.class); System.out.println(userDto); // UserDto{username='jack', age=23, young=false} assert user.getUsername().equals(userDto.getUsername()); assert user.getAge() == userDto.getAge(); assert user.isYoung() == userDto.isYoung(); User newUser = converter.convert(userDto, User.class); System.out.println(newUser); // User{username='jack', age=23, young=false} assert user.getUsername().equals(newUser.getUsername()); assert user.getAge() == newUser.getAge(); assert user.isYoung() == newUser.isYoung(); } } ``` -------------------------------- ### Retrieving Mapper Instance with Mappers Factory Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/mapstruct/1-5-5-Final.md Demonstrates how to obtain a mapper instance using the Mappers.getMapper() method when not using a dependency injection framework. ```java CarMapper mapper = Mappers.getMapper( CarMapper.class ); ``` -------------------------------- ### Add MapStruct Plus Solon Plugin Dependencies Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/en/introduction/quick-start.md Configures Maven to include the mapstruct-plus-solon-plugin and sets up the compiler plugin with the mapstruct-plus-processor and a Solon-specific annotation argument. ```xml org.dromara.solon-plugins mapstruct-plus-solon-plugins org.apache.maven.plugins maven-compiler-plugin 3.8.1 ${java.version} ${java.version} io.github.linpeilie mapstruct-plus-processor ${mapstruct-plus.version} -Amapstruct.defaultComponentModel=solon ``` -------------------------------- ### Inject Mapper via Dependency Injection Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/mapstruct/1-5-5-Final.md Demonstrates injecting a mapper instance using the @Inject annotation. ```java @Inject private CarMapper mapper; ``` -------------------------------- ### Configure MapStructPlus with Maven Compiler Args Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/en/guide/configuration.md Configure MapStructPlus settings by adding compilation parameters to the compiler, such as using the compilerArgs property in the maven-compiler-plugin. This method takes precedence over configuration classes. ```xml org.apache.maven.plugins maven-compiler-plugin 3.8.0 ${maven.compiler.source} ${maven.compiler.target} org.projectlombok lombok ${lombok.version} io.github.linpeilie mapstruct-plus-processor ${mapstruct-plus.version} org.projectlombok lombok-mapstruct-binding 0.2.0 -Amapstruct.plus.adapterClassName=DemoConvertMapperAdapter -Amapstruct.plus.adapterPackage=io.github.linpeilie.adapter -Amapstruct.plus.mapAdapterClassName=DemoMapConvertMapperAdapter ``` -------------------------------- ### Abstract Mapper Class with INSTANCE Property Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/mapstruct/1-5-5-Final.md Illustrates defining a static INSTANCE property in an abstract mapper class for singleton access, similar to interface-based mappers. ```java @Mapper public abstract class CarMapper { public static final CarMapper INSTANCE = Mappers.getMapper( CarMapper.class ); CarDto carToCarDto(Car car); } ``` -------------------------------- ### Maven Dependencies and Compiler Plugin Configuration Source: https://github.com/linpeilie/mapstruct-plus/blob/main/README.md Includes the mapstruct-plus-spring-boot-starter dependency and configures the Maven compiler plugin to use the mapstruct-plus-processor. ```xml latest version io.github.linpeilie mapstruct-plus-spring-boot-starter ${mapstruct-plus.version} org.apache.maven.plugins maven-compiler-plugin 3.8.1 1.8 1.8 io.github.linpeilie mapstruct-plus-processor ${mapstruct-plus.version} ``` -------------------------------- ### Configure MapStructPlus with @MapperConfig Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/en/guide/configuration.md Create a configuration class annotated with @MapperConfig in the module that needs configuration. Only one such class is allowed per module, and it must be placed within the module to be effective. ```java import io.github.linpeilie.annotations.MapperConfig; @MapperConfig(adapterClassName = "DemoConvertMapperAdapter", adapterPackage = "io.github.linpeilie.adapter", mapAdapterClassName = "DemoMapConvertMapperAdapter") public class MapStructPlusConfiguration { } ``` -------------------------------- ### Configure Lombok and MapStruct Plus dependencies Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/en/guide/faq.md Add these dependencies to your build configuration to enable annotation processing for MapStruct Plus and Lombok. ```xml org.apache.maven.plugins maven-compiler-plugin 3.8.1 1.8 1.8 org.projectlombok lombok ${lombok.version} io.github.linpeilie mapstruct-plus-processor ${mapstruct-plus.version} org.projectlombok lombok-mapstruct-binding 0.2.0 ``` ```groovy dependencies { annotationProcessor group: 'org.projectlombok', name: 'lombok', version: {lombok.version} annotationProcessor group: 'io.github.linpeilie', name: 'mapstruct-plus-processor', version: ${mapstruct-plus.version} annotationProcessor group: 'org.projectlombok', name: 'lombok-mapstruct-binding', version: '0.2.0' } ``` -------------------------------- ### Configure Gradle for Non-SpringBoot Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/en/introduction/install.md Include the mapstruct-plus implementation and annotation processor dependencies. ```groovy dependencies { implementation 'io.github.linpeilie:mapstruct-plus:latest version' annotationProcessor 'io.github.linpeilie:mapstruct-plus-processor:latest version' } ``` -------------------------------- ### Define Reusable Mapping with Meta-Annotation Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/mapstruct/1-5-5-Final.md Use meta-annotations to define reusable mapping configurations. This allows applying a set of @Mapping annotations to multiple methods or interfaces, promoting consistency and reducing boilerplate. ```java @Retention(RetentionPolicy.CLASS) @Mapping(target = "id", ignore = true) @Mapping(target = "creationDate", expression = "java(new java.util.Date())") @Mapping(target = "name", source = "groupName") public @interface ToEntity { } ``` -------------------------------- ### Add mapstruct-plus-solon-plugin Dependency Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/introduction/quick-start.md Include the mapstruct-plus-solon-plugin dependency in your project's pom.xml. This plugin is managed within the solon-parent dependency management. ```xml org.dromara.solon-plugins mapstruct-plus-solon-plugins org.apache.maven.plugins maven-compiler-plugin 3.8.1 ${java.version} ${java.version} io.github.linpeilie mapstruct-plus-processor ${mapstruct-plus.version} -Amapstruct.defaultComponentModel=solon ``` -------------------------------- ### Configure Maven for Non-SpringBoot Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/en/introduction/install.md Add the mapstruct-plus dependency and configure the annotation processor path in the maven-compiler-plugin. ```xml latest version io.github.linpeilie mapstruct-plus ${mapstruct-plus.version} org.apache.maven.plugins maven-compiler-plugin 3.8.1 1.8 1.8 io.github.linpeilie mapstruct-plus-processor ${mapstruct-plus.version} ``` -------------------------------- ### User Class Definition Source: https://github.com/linpeilie/mapstruct-plus/blob/main/README.md Defines the User class with basic fields. Ensure getter, setter, toString, equals, and hashCode methods are implemented. ```java public class User { private String username; private int age; private boolean young; // getter、setter、toString、equals、hashCode } ``` -------------------------------- ### Maven Configuration for Lombok Integration Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/en/guide/faq.md Configure the Maven compiler plugin to integrate Lombok with MapStructPlus for versions before Lombok 1.18.16. Ensure both Lombok and MapStructPlus annotation processors are included. ```xml org.apache.maven.plugins maven-compiler-plugin 3.8.1 1.8 1.8 org.projectlombok lombok ${LOMBOK.version} io.github.linpeilie mapstruct-plus-processor ${mapstruct-plus.version} ``` -------------------------------- ### Customer Class for Map to Bean Mapping Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/mapstruct/1-5-5-Final.md A simple Customer class with id and name properties, used as a target for mapping from a Map. ```java public class Customer { private Long id; private String name; //getters and setter omitted for brevity } ``` -------------------------------- ### Mapper Interface with INSTANCE Property Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/mapstruct/1-5-5-Final.md Shows the convention of defining a static INSTANCE property within a mapper interface to hold a singleton instance, retrieved via Mappers.getMapper(). ```java @Mapper public interface CarMapper { CarMapper INSTANCE = Mappers.getMapper( CarMapper.class ); CarDto carToCarDto(Car car); } ``` -------------------------------- ### Person Class with Constructor Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/mapstruct/1-5-5-Final.md Defines a Person class with a constructor that takes name and surname as arguments, intended for MapStruct mapping. ```java public class Person { private final String name; private final String surname; public Person(String name, String surname) { this.name = name; this.surname = surname; } } ``` -------------------------------- ### Add Maven Dependency for MapStruct-Plus Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/introduction/quick-start.md Include the mapstruct-plus-spring-boot-starter and mapstruct-plus-processor dependencies in your Maven project. Ensure you configure the Maven compiler plugin to use the annotation processor. ```xml 最新版本 io.github.linpeilie mapstruct-plus-spring-boot-starter ${mapstruct-plus.version} org.apache.maven.plugins maven-compiler-plugin 3.8.1 1.8 1.8 io.github.linpeilie mapstruct-plus-processor ${mapstruct-plus.version} ``` -------------------------------- ### Add Gradle Dependency for MapStruct-Plus Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/introduction/quick-start.md Add the mapstruct-plus-spring-boot-starter and mapstruct-plus-processor dependencies to your Gradle project. Ensure the annotation processor is correctly configured. ```groovy dependencies { implementation group: 'io.github.linpeilie', name: 'mapstruct-plus-spring-boot-starter', version: ${mapstruct-plus.version} annotationProcessor group: 'io.github.linpeilie', name: 'mapstruct-plus-processor', version: ${mapstruct-plus.version} } ``` -------------------------------- ### Configure MapStruct Options in Maven Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/mapstruct/1-5-5-Final.md Use the `compilerArgs` property within the Maven compiler plugin to pass MapStruct annotation processor options. Ensure `showWarnings` is set to `true` for verbose mode when using Maven. ```xml ... org.apache.maven.plugins maven-compiler-plugin 3.5.1 1.8 1.8 org.mapstruct mapstruct-processor ${org.mapstruct.version} true -Amapstruct.suppressGeneratorTimestamp=true -Amapstruct.suppressGeneratorVersionInfoComment=true -Amapstruct.verbose=true ... ``` -------------------------------- ### Map From Multiple Source Parameters Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/mapstruct/1-5-5-Final.md Combine data from multiple source objects into a single DTO. Explicitly specify the source for properties with the same name across different source objects using @Mapping. ```java @Mapper public interface AddressMapper { @Mapping(target = "description", source = "person.description") @Mapping(target = "houseNumber", source = "address.houseNo") DeliveryAddressDto personAndAddressToDeliveryAddressDto(Person person, Address address); } ``` -------------------------------- ### Configure Constructor Injection Strategy Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/mapstruct/1-5-5-Final.md Sets the injection strategy to constructor-based injection for the mapper implementation. ```java @Mapper(componentModel = MappingConstants.ComponentModel.CDI, uses = EngineMapper.class, injectionStrategy = InjectionStrategy.CONSTRUCTOR) public interface CarMapper { CarDto carToCarDto(Car car); } ``` -------------------------------- ### Configure specific transformation rules for multiple targets Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/en/guide/multiple-class-convert.md Apply target-specific mapping rules by setting the targetClass attribute in @AutoMapping or @AutoMappings. Rules without a targetClass apply to all target conversions. ```java @Data @AutoMappers({ @AutoMapper(target = UserDto.class), @AutoMapper(target = UserVO.class) }) public class User { private String username; private int age; private boolean young; @AutoMapping(targetClass = UserDto.class, target = "educations", expression = "java(java.lang.String.join(\",\", source.getEducationList()))") private List educationList; @AutoMappings({ @AutoMapping(targetClass = UserDto.class, dateFormat = "yyyy-MM-dd HH:mm:ss"), @AutoMapping(targetClass = UserVO.class, ignore = true) }) private Date birthday; @AutoMapping(targetClass = UserDto.class, numberFormat = "$0.00") private double assets; @AutoMapping(numberFormat = "$0.00") private double money; @AutoMappings({ @AutoMapping(targetClass = UserVO.class, target = "voField") }) private String voField; } ``` -------------------------------- ### Testing Custom Type Converter Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/en/guide/class-convert.md Test the custom type converter by performing a conversion and asserting the result. Ensure the converter is correctly integrated and functions as expected. ```java @SpringBootTest public class QuickStartTest { @Autowired private Converter converter; @Test public void ueseTest() { UserDto userDto = new UserDto(); userDto.setEducations("1,2,3"); final User user = converter.convert(userDto, User.class); System.out.println(user.getEducationList()); // [1, 2, 3] assert user.getEducationList().size() == 3; } } ``` -------------------------------- ### Gradle Configuration for Lombok Integration Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/en/guide/faq.md Add Lombok and MapStructPlus annotation processors as dependencies in your Gradle build file for integration. This applies to versions before Lombok 1.18.16. ```groovy dependencies { annotationProcessor group: 'org.projectlombok', name: 'lombok', version: {lombok.version} annotationProcessor group: 'io.github.linpeilie', name: 'mapstruct-plus-processor', version: ${mapstruct-plus.version} } ``` -------------------------------- ### Generated CarToCarDtoMapperImpl Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/en/guide/class-convert.md The generated implementation class for converting Car to CarDto. It utilizes the custom TyreMapper for nested type conversions. ```java @Generated( value = "org.mapstruct.ap.MappingProcessor", date = "2023-04-24T15:38:48+0800", comments = "version: 1.5.5.Final, compiler: javac, environment: Java 1.8.0_202 (Oracle Corporation)" ) @Component public class CarToCarDtoMapperImpl implements CarToCarDtoMapper { @Autowired private TyreMapper tyreMapper; @Override public CarDto convert(Car source) { if ( source == null ) { return null; } CarDto carDto = new CarDto(); carDto.setTyre( tyreMapper.tyreToTyreDTO( source.getTyre() ) ); return carDto; } @Override public CarDto convert(Car source, CarDto target) { if ( source == null ) { return target; } target.setTyre( tyreMapper.tyreToTyreDTO( source.getTyre() ) ); return target; } } ``` -------------------------------- ### Test Enum Conversion Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/en/guide/enum-convert.md Verify enum conversions between objects using the converter. This test demonstrates converting from `Goods` to `GoodsVo` and back. ```java @Test public void enumMapTest() { final GoodsVo goodsVo = converter.convert(goods, GoodsVo.class); System.out.println(goodsVo); Assert.equals(goodsVo.getState(), goods.getState().getState()); final Goods goods2 = converter.convert(goodsVo, Goods.class); System.out.println(goods2); Assert.equals(goods2.getState(), GoodsStateEnum.ENABLED); } ``` -------------------------------- ### Configure MapStruct Options in Gradle Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/mapstruct/1-5-5-Final.md Add MapStruct annotation processor options to the `compilerArgs` in your Gradle build script for Java compilation. ```groovy ... compileJava { options.compilerArgs += [ '-Amapstruct.suppressGeneratorTimestamp=true', '-Amapstruct.suppressGeneratorVersionInfoComment=true', '-Amapstruct.verbose=true' ] } ... ``` -------------------------------- ### Define Custom Conversion Interface Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/guide/class-convert.md Interface for converting between Tyre and TyreDTO using MapStruct. ```java @Mapper(componentModel = MappingConstants.ComponentModel.SPRING) public interface TyreMapper { TyreDTO tyreToTyreDTO(Tyre tyre); Tyre tyreDtoToTyre(TyreDTO tyreDTO); } ``` -------------------------------- ### Generated CustomerMapper Implementation Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/mapstruct/1-5-5-Final.md The generated implementation for CustomerMapper, demonstrating how MapStruct extracts values from a Map to populate a Customer object, including custom source field mapping. ```java // GENERATED CODE public class CustomerMapperImpl implements CustomerMapper { @Override public Customer toCustomer(Map map) { // ... if ( map.containsKey( "id" ) ) { customer.setId( Integer.parseInt( map.get( "id" ) ) ); } if ( map.containsKey( "customerName" ) ) { customer.setName( map.get( "customerName" ) ); } // ... } } ``` -------------------------------- ### Define Target Classes for Mapping Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/en/guide/map-to-class.md Annotate target classes with @AutoMapMapper to enable automatic generation of mapping logic. ```java @AutoMapMapper @Data public class MapModelA { private String str; private int i1; private Long l2; private MapModelB mapModelB; } ``` ```java @AutoMapMapper @Data public class MapModelB { private Date date; } ``` -------------------------------- ### Configure AutoMapper with cycleAvoiding Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/en/guide/cycle-avoiding.md Enable cycle avoidance by setting the cycleAvoiding attribute to true in the @AutoMapper annotation. ```java @Data @AutoMapper(target = TreeNodeDto.class, cycleAvoiding = true) public class TreeNode { private TreeNode parent; private List children; } @Data @AutoMapper(target = TreeNode.class, cycleAvoiding = true) public class TreeNodeDto { private TreeNodeDto parent; private List children; } ``` -------------------------------- ### Converter Class Methods Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/en/guide/converter-api.md The Converter class provides methods to perform type conversions between different object types and collections. ```APIDOC ## Converter Class API ### Description The `Converter` class is used to perform concrete transformation logic between different types. ### Methods #### 1. Convert single object to a new instance **Method Signature:** ` T convert(S source, Class targetType)` **Description:** Converts a source object to a new instance of the specified target type. #### 2. Convert single object to an existing instance **Method Signature:** ` T convert(S source, T target)` **Description:** Converts properties from the source object to an existing target object. Returns the modified target object. #### 3. Convert a list of objects **Method Signature:** ` List convert(List source, Class targetType)` **Description:** Converts a list of source objects to a list of target type objects. #### 4. Convert a Map to an object **Method Signature:** ` T convert(Map map, Class target)` **Description:** Converts a `Map` to an instance of the specified target type. ``` -------------------------------- ### Generated Mapper Implementations Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/guide/class-convert.md Generated implementation classes that automatically reference the custom TyreMapper. ```java @Generated( value = "org.mapstruct.ap.MappingProcessor", date = "2023-04-24T15:38:48+0800", comments = "version: 1.5.5.Final, compiler: javac, environment: Java 1.8.0_202 (Oracle Corporation)" ) @Component public class CarToCarDtoMapperImpl implements CarToCarDtoMapper { @Autowired private TyreMapper tyreMapper; @Override public CarDto convert(Car source) { if ( source == null ) { return null; } CarDto carDto = new CarDto(); carDto.setTyre( tyreMapper.tyreToTyreDTO( source.getTyre() ) ); return carDto; } @Override public CarDto convert(Car source, CarDto target) { if ( source == null ) { return target; } target.setTyre( tyreMapper.tyreToTyreDTO( source.getTyre() ) ); return target; } } ``` ```java @Generated( value = "org.mapstruct.ap.MappingProcessor", date = "2023-04-24T15:38:49+0800", comments = "version: 1.5.5.Final, compiler: javac, environment: Java 1.8.0_202 (Oracle Corporation)" ) @Component public class CarDtoToCarMapperImpl implements CarDtoToCarMapper { @Autowired private TyreMapper tyreMapper; @Override public Car convert(CarDto source) { if ( source == null ) { return null; } Car car = new Car(); car.setTyre( tyreMapper.tyreDtoToTyre( source.getTyre() ) ); return car; } @Override public Car convert(CarDto source, Car target) { if ( source == null ) { return target; } target.setTyre( tyreMapper.tyreDtoToTyre( source.getTyre() ) ); return target; } } ``` -------------------------------- ### Define CarMapper Interface with Mappings Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/mapstruct/1-5-5-Final.md Define a Java interface with @Mapper annotation and methods for object conversion. Use @Mapping to specify source and target property names when they differ. ```java @Mapper public interface CarMapper { @Mapping(target = "manufacturer", source = "make") @Mapping(target = "seatCount", source = "numberOfSeats") CarDto carToCarDto(Car car); @Mapping(target = "fullName", source = "name") PersonDto personToPersonDto(Person person); } ``` -------------------------------- ### Map Nested Object Properties Using Target '.' Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/mapstruct/1-5-5-Final.md Configure the target parameter as '.' to map all properties of a nested bean to the target object without explicit naming. Use explicit @Mapping to resolve naming conflicts. ```java @Mapper public interface CustomerMapper { @Mapping( target = "name", source = "record.name" ) @Mapping( target = ".", source = "record" ) @Mapping( target = ".", source = "account" ) Customer customerDtoToCustomer(CustomerDto customerDto); } ``` -------------------------------- ### Simple Class Conversion with @AutoMapper Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/en/guide/class-convert.md Annotate a class with @AutoMapper to enable conversion to a target class. MapStruct Plus generates mapper interfaces for both source-to-target and target-to-source conversions by default. ```java @AutoMapper(target = CarDto.class) public class Car { // ... } ``` -------------------------------- ### PersonMapper Interface Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/mapstruct/1-5-5-Final.md An interface defining a mapping method from PersonDto to Person, utilizing constructor mapping. ```java public interface PersonMapper { Person map(PersonDto dto); } ``` -------------------------------- ### Convert Map to Object in Test Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/en/guide/map-to-class.md Use the Converter bean to perform the conversion from a Map to the target class instance. ```java @SpringBootTest public class QuickStartTest { @Autowired private Converter converter; @Test public void test() { Map mapModel1 = new HashMap<>(); mapModel1.put("str", "1jkf1ijkj3f"); mapModel1.put("i1", 111); mapModel1.put("l2", 11231); Map mapModel2 = new HashMap<>(); mapModel2.put("date", DateUtil.parse("2023-02-23 01:03:23")); mapModel1.put("mapModelB", mapModel2); final MapModelA mapModelA = converter.convert(mapModel1, MapModelA.class); System.out.println(mapModelA); // MapModelA(str=1jkf1ijkj3f, i1=111, l2=11231, mapModelB=MapModelB(date=2023-02-23 01:03:23)) } } ``` -------------------------------- ### Configure Number Formatting for String Conversion Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/guide/class-convert.md Use @AutoMapping's numberFormat to specify formats for converting between numeric types and String. This format must be supported by java.text.DecimalFormat. ```java @Data @AutoMapper(target = OrderEntity.class) public class Order { @AutoMapping(numberFormat = "$0.00") private BigDecimal orderPrice; @AutoMapping(numberFormat = "$0.00") private Integer goodsNum; } ``` ```java @Data @AutoMapper(target = Order.class) public class OrderEntity { @AutoMapping(numberFormat = "$0.00") private String orderPrice; @AutoMapping(numberFormat = "$0.00") private String goodsNum; } ``` -------------------------------- ### UserDto Class Definition Source: https://github.com/linpeilie/mapstruct-plus/blob/main/README.md Defines the UserDto class with basic fields. Ensure getter, setter, toString, equals, and hashCode methods are implemented. ```java public class UserDto { private String username; private int age; private boolean young; // getter、setter、toString、equals、hashCode } ``` -------------------------------- ### Generated CarDtoToCarMapperImpl Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/en/guide/class-convert.md The generated implementation class for converting CarDto to Car. It leverages the custom TyreMapper for nested type conversions. ```java @Generated( value = "org.mapstruct.ap.MappingProcessor", date = "2023-04-24T15:38:49+0800", comments = "version: 1.5.5.Final, compiler: javac, environment: Java 1.8.0_202 (Oracle Corporation)" ) @Component public class CarDtoToCarMapperImpl implements CarDtoToCarMapper { @Autowired private TyreMapper tyreMapper; @Override public Car convert(CarDto source) { if ( source == null ) { return null; } Car car = new Car(); car.setTyre( tyreMapper.tyreDtoToTyre( source.getTyre() ) ); return car; } @Override public Car convert(CarDto source, Car target) { if ( source == null ) { return target; } target.setTyre( tyreMapper.tyreDtoToTyre( source.getTyre() ) ); return target; } } ``` -------------------------------- ### Define custom conversion methods with @Named Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/en/guide/class-convert.md Implement transformation logic in a separate component and annotate methods with @Named to make them available for mapping. ```java @Component @Named("TitleTranslator") public class Titles { @Named("EnglishToFrench") public String translateTitleEF(String title) { if ("One Hundred Years of Solitude".equals(title)) { return "Cent ans de solitude"; } return "Inconnu et inconnu"; } @Named("FrenchToEnglish") public String translateTitleFE(String title) { if ("Cent ans de solitude".equals(title)) { return "One Hundred Years of Solitude"; } return "Unknown"; } } ``` -------------------------------- ### Test Object Mapping with MapStruct-Plus Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/introduction/quick-start.md This test demonstrates converting between User and UserDto objects using the injected Converter in a Spring Boot application. It verifies both forward and reverse conversions. ```java @SpringBootTest public class QuickStartTest { @Autowired private Converter converter; @Test public void test() { User user = new User(); user.setUsername("jack"); user.setAge(23); user.setYoung(false); UserDto userDto = converter.convert(user, UserDto.class); System.out.println(userDto); // UserDto{username='jack', age=23, young=false} assert user.getUsername().equals(userDto.getUsername()); assert user.getAge() == userDto.getAge(); assert user.isYoung() == userDto.isYoung(); User newUser = converter.convert(userDto, User.class); System.out.println(newUser); // User{username='jack', age=23, young=false} assert user.getUsername().equals(newUser.getUsername()); assert user.getAge() == newUser.getAge(); assert user.isYoung() == newUser.isYoung(); } } ``` -------------------------------- ### Define Mapper with CDI Component Model Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/mapstruct/1-5-5-Final.md Configures a mapper to use the CDI component model, resulting in an @ApplicationScoped implementation. ```java @Mapper(componentModel = MappingConstants.ComponentModel.CDI) public interface CarMapper { CarDto carToCarDto(Car car); } ``` -------------------------------- ### Maven Dependency for MapStruct Plus Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/README.md Add this dependency to your Maven project to include MapStruct Plus and its Spring Boot starter. ```xml io.github.linpeilie mapstruct-plus-spring-boot-starter 1.5.1 ``` -------------------------------- ### Apply Meta-Annotation for Entity Mapping Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/mapstruct/1-5-5-Final.md Apply a custom meta-annotation like @ToEntity to mapping methods in an interface. This assumes common properties across different source and target types, enabling a 'duck typing' approach to mapping. ```java @Mapper public interface StorageMapper { StorageMapper INSTANCE = Mappers.getMapper( StorageMapper.class ); @ToEntity @Mapping( target = "weightLimit", source = "maxWeight") ShelveEntity map(ShelveDto source); @ToEntity @Mapping( target = "label", source = "designation") BoxEntity map(BoxDto source); } ``` -------------------------------- ### Ignore Property Mapping with @AutoMapping Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/guide/class-convert.md Configure @AutoMapping with 'ignore = true' to exclude specific properties from the mapping process. ```java @AutoMapper(target = CarDto.class) @Data public class Car { @AutoMapping(target = "wheels", ignore = true) private Wheels wheels; } ``` -------------------------------- ### Configure multiple class conversions with @AutoMappers Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/en/guide/multiple-class-convert.md Use the @AutoMappers annotation to define multiple target classes for a single source class. ```java @Data @AutoMappers({ @AutoMapper(target = UserDto.class), @AutoMapper(target = UserVO.class) }) public class User { // fields } ``` -------------------------------- ### Generated PersonMapper Implementation Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/mapstruct/1-5-5-Final.md The generated implementation of PersonMapper, showing how MapStruct uses the Person constructor to create a Person object from a PersonDto. ```java // GENERATED CODE public class PersonMapperImpl implements PersonMapper { public Person map(PersonDto dto) { if (dto == null) { return null; } String name; String surname; name = dto.getName(); surname = dto.getSurname(); Person person = new Person( name, surname ); return person; } } ``` -------------------------------- ### Map Nested Source Properties Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/en/guide/class-convert.md Configure the `source` attribute in @AutoMapping to map a nested property from the source object to a target property. This allows mapping fields like `sku.price` to `price`. ```java @Data @AutoMapper(target = GoodsVo.class, reverseConvertGenerate = false) public class Goods { @AutoMapping(source = "sku.price", target = "price") private Sku sku; } ``` ```java @Data public class GoodsVo { private Integer price; } ``` -------------------------------- ### Gradle Dependency for MapStruct Plus Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/README.md Add this dependency to your Gradle project to include MapStruct Plus and its Spring Boot starter. ```groovy implementation group: 'io.github.linpeilie', name: 'mapstruct-plus-spring-boot-starter', version: '1.5.1' ``` -------------------------------- ### Specify Enums for Cross-Module Support Source: https://github.com/linpeilie/mapstruct-plus/blob/main/docs/en/guide/enum-convert.md When enums and their usage are in different modules, use the `useEnums` attribute in `@AutoMapper` to specify the enum classes for conversion. ```java @AutoMapper(target = GoodsVo.class, reverseConvertGenerate = false, useEnums = {GoodsStateEnum.class}) public class Goods { private GoodsStateEnum state; } ```