preface

In today’s microservices projects, projects are mostly layered. Generally, DO will not be dependent on external services. In this case, DTOS need to be placed in modules providing external interfaces for object transmission, that is, DO objects for internal and DTO objects for external. Dtos can be changed according to business needs without mapping all attributes of DO. Then there is a problem, we need to convert the DTO DO, so we can only get out of the DTO one by one, and then put into DO one by one.

Such object-to-object conversions require a tool dedicated to solving conversion problems, since getting /set for every field is cumbersome and untechnical. (Not limited to DO to DTO)

Import dependence

<dependency>
	<groupId>org.projectlombok</groupId>
	<artifactId>lombok</artifactId>
</dependency>
 <! -- Contains required comments such as @mapping -->
<dependency>
	<groupId>org.mapstruct</groupId>
	<artifactId>mapstruct-jdk8</artifactId>
	<version>1.2.0. The Final</version>
</dependency>
<! -- Comment handler containing the implementation of the generated mapper -->
<dependency>
	<groupId>org.mapstruct</groupId>
	<artifactId>mapstruct-processor</artifactId>
	<version>1.2.0. The Final</version>
</dependency>
Copy the code

The instance

Exactly the same properties

Start by creating two classes, UserDTO and UserDO. Note: These two classes are exactly the same

  • UserDO
@Data
public class UserDO {

    private Long id;
    private String userName;
    
}
Copy the code
  • UserDTO
@Data
public class UserDTO {

    private Long id;
    private String userName;
    
}
Copy the code

Then write a Java interface, add annotation @mapper on the interface, provide the userDOToUserDTO method for conversion, UserDO conversion to UserDTO. Notice the guide package at @mapper

  • MapStructConverter
import com.gongj.mapstruct.data.UserDO;
import com.gongj.mapstruct.dto.UserDTO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;

@Mapper
public interface MapStructConverter {

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

    UserDTO userDOToUserDTO(UserDO userDO);
}
Copy the code

When the source object (UserDO) attribute name is the same as the target object (UserDTO) attribute name, it is mapped implicitly

  • Writing test classes

@Test
    void contextLoads(a) {
        UserDO userDo = new UserDO();
        userDo.setId(8888L);
        userDo.setUserName("gongjie");
        
        System.out.println("userDo = "+ userDo.toString());
        // Call the transform method to pass the source object to UserDO
        UserDTO userDTO = MapStructConverter.INSTANCE.userDOToUserDTO(userDo);
        System.out.println("userDTO = "+ userDTO.toString()); } userDo = userDo (id= userDo8888, userName=gongjie)
userDTO = UserDTO(id=8888, userName=gongjie)
Copy the code

You can see the result is already what I want. So how does it work? After we run the test method,mapstructIt is automatically generated in the target directoryMapStructConverterCorresponding implementation class.Let’s seeMapStructConverterImplContent:

@Generated( value = "org.mapstruct.ap.MappingProcessor", date = "2020-12-03T12:42:12+0800", comments = "version: Final, Compiler: JavAC, Environment: Java 1.8.0_271 (Oracle Corporation)")
public class MapStructConverterImpl implements MapStructConverter {

     @Override
    public UserDTO userDOToUserDTO(UserDO userDO) {
        if ( userDO == null ) {
            return null;
        }

        UserDTO userDTO = new UserDTO();

        userDTO.setId( userDO.getId() );
        userDTO.setUserName( userDO.getUserName() );

        returnuserDTO; }}Copy the code

After looking at the source code it generated, don’t you feel great?

Attribute names are inconsistent

We’ve used Mapstruct briefly above. If the source object attribute name is the same as the target object attribute name, the corresponding attribute is automatically mapped. What if the property names are inconsistent? Next add attributes to UserDTO and UserDO, respectively.

  • UserDO
@Data
public class UserDO {

    /** * add */
    private String email;
   
}
Copy the code
  • UserDTO
@Data
public class UserDTO {
	
	/** * add */
	// The name is inconsistent
	private String userEmail;
}
Copy the code
  • MapStructConverterIf the two objects have different names, you can pass@MappingThe annotation specifies the mapping of its name
    @Mappings( { @Mapping(source = "email", target = "userEmail"), } )
    UserDTO userDOToUserDTO(UserDO userDO);
Copy the code
  • test
	 @Test
    void contextLoads2(a) {
        UserDO userDo = new UserDO();
        userDo.setId(8888L);
        userDo.setUserName("gongjie");
        userDo.setEmail("[email protected]");
        System.out.println("userDo = "+ userDo.toString());
        // Call the transform method to pass the source object to UserDO
        UserDTO userDTO = MapStructConverter.INSTANCE.userDOToUserDTO(userDo);
        System.out.println("userDTO = "+ userDTO.toString()); } result: userDo = userDo (id=8888, userName=gongjie, email=1998@163.com)
userDTO = UserDTO(id=8888, userName=gongjie, userEmail=1998@163.com)
Copy the code

Note: If the Test method does not yield the desired results after the new properties are added, you need to remove the previously automatically generated implementation class (or remove the target directory) and then recompile

  • The source code
 @Override
    public UserDTO userDOToUserDTO(UserDO userDO) {
        if ( userDO == null ) {
            return null;
        }

        UserDTO userDTO = new UserDTO();

        userDTO.setUserEmail( userDO.getEmail() );
        userDTO.setId( userDO.getId() );
        userDTO.setUserName( userDO.getUserName() );

        return userDTO;
    }
Copy the code

Time format conversion

Add attributes birthday and time, Date and String respectively

  • UserDO
@Data
public class UserDO {

    /** * add */
    private Date birthday;
    
    private String time;
   
}
Copy the code
  • UserDTO

Add two attributes date and userBirthday, one of type date and one of type String

@Data
public class UserDTO {

	/** * add */
	// The name and type are inconsistent
    private String userBirthday;
    
	 // The name and type are inconsistent
    private Date userTime;
    
}
Copy the code
  • The userDOToUserDTO of MapStructConverter is modified again, where userBirthday and userTime are formatted using dateFormat.

     @Mappings({ @Mapping(source = "birthday", target = "userBirthday",dateFormat = "yyyy-MM-dd HH:mm:ss"), @Mapping(source = "time", target = "userTime",dateFormat = "yyyy-MM-dd"), @Mapping(source = "email", target = "userEmail"), } )
        UserDTO userDOToUserDTO(UserDO userDO);
    Copy the code
  • test

	  @Test
    void test1(a){
        UserDO userDo = new UserDO();
        userDo.setId(8888L);
        userDo.setUserName("gongjie");
        userDo.setBirthday(new Date());
        userDo.setTime("2021-05-09");
        userDo.setEmail("[email protected]");
        System.out.println("userDo = "+ userDo.toString());
        UserDTO userDTO = MapStructConverter.INSTANCE.userDOToUserDTO(userDo);
        System.out.println("userDTO = "+ userDTO.toString()); } result: userDo = userDo (id=8888, userName=gongjie, birthday=Sun May 09 21:59:20 CST 2021, time=2021-05-09, email=99@163.com)
    
userDTO = UserDTO(id=8888, userName=gongjie, userBirthday=2021-05- 0921:59:20, userTime=Sun May 09 00:00:00 CST 2021, userEmail=99@163.com)
Copy the code
  • The source code

    @Override
        public UserDTO userDOToUserDTO(UserDO userDO) {
            if ( userDO == null ) {
                return null;
            }
    
            UserDTO userDTO = new UserDTO();
    
            userDTO.setUserEmail( userDO.getEmail() );
            try {
                if( userDO.getTime() ! =null ) {
                    userDTO.setUserTime( new SimpleDateFormat( "yyyy-MM-dd").parse( userDO.getTime() ) ); }}catch ( ParseException e ) {
                throw new RuntimeException( e );
            }
            if( userDO.getBirthday() ! =null ) {
              userDTO.setUserBirthday( new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ).format( userDO.getBirthday() ) );
            }
            userDTO.setId( userDO.getId() );
            userDTO.setUserName( userDO.getUserName() );
    
            return userDTO;
        }
    Copy the code

    The source code uses SimpleDateFormat for time formatting.

Ignore the attribute

Normally, the ID of DO is not returned to the DTO, and we can use the ignore attribute to ignore the transformation field.

 @Mappings({ @Mapping(source = "id",target = "id",ignore = true), @Mapping(source = "birthday", target = "userBirthday",dateFormat = "yyyy-MM-dd HH:mm:ss"), @Mapping(source = "time", target = "userTime",dateFormat = "yyyy-MM-dd"), @Mapping(source = "email", target = "userEmail"), } )
    UserDTO userDOToUserDTO(UserDO userDO); Result: userDo = userDo (id=8888, userName=gongjie, birthday=Sun May 09 22:03:15 CST 2021, time=2021-05-09, email=99@163.com)
// The ID attribute in the DTO is null
userDTO = UserDTO(id=null, userName=gongjie, userBirthday=2021-05- 0922:03:15, userTime=Sun May 09 00:00:00 CST 2021, userEmail=99@163.com)
Copy the code

Collection of conversion

MapStructConverter new method userDOToUserDTOs:

  List<UserDTO> userDOToUserDTOs(List<UserDO> userDO);
Copy the code
  • test
	void test2(a){

        ArrayList<UserDO> objects = new ArrayList<>();
        UserDO userDo = new UserDO();
        userDo.setId(8888L);
        userDo.setUserName("gongjie");
        userDo.setBirthday(new Date());
        userDo.setTime("2021-05-09");
        userDo.setEmail("[email protected]");
        System.out.println("userDo = "+ userDo.toString());
        objects.add(userDo);
        List<UserDTO> userDTOS = MapStructConverter.INSTANCE.userDOToUserDTOs(objects);
        System.out.println("userDTO = "+ userDTOS.toString()); } result: userDo = userDo (id=8888, userName=gongjie, birthday=Sun May 09 22:04:47 CST 2021, time=2021-05-09, email=99@163.com)
    
userDTO = [UserDTO(id=null, userName=gongjie, userBirthday=2021-05- 0922:04:47, userTime=Sun May 09 00:00:00 CST 2021, userEmail=99@163.com)]
Copy the code
  • The source code
@Override
   public List<UserDTO> userDOToUserDTOs(List<UserDO> userDO) {
       if ( userDO == null ) {
           return null;
       }

       List<UserDTO> list = new ArrayList<UserDTO>( userDO.size() );
       for ( UserDO userDO1 : userDO ) {
           list.add( userDOToUserDTO( userDO1 ) );
       }

       return list;
   }

@Override
   public UserDTO userDOToUserDTO(UserDO userDO) {
       if ( userDO == null ) {
           return null;
       }

       UserDTO userDTO = new UserDTO();

       userDTO.setUserEmail( userDO.getEmail() );
       try {
           if( userDO.getTime() ! =null ) {
               userDTO.setUserTime( new SimpleDateFormat( "yyyy-MM-dd").parse( userDO.getTime() ) ); }}catch ( ParseException e ) {
           throw new RuntimeException( e );
       }
       if( userDO.getBirthday() ! =null ) {
           userDTO.setUserBirthday( new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ).format( userDO.getBirthday() ) );
       }
       userDTO.setUserName( userDO.getUserName() );

       return userDTO;
   }
Copy the code

You can see that inside the userDOToUserDTOs method is actually calling the userDOToUserDTO method. Why is that? Because mapStruct matches by type. The target and source types of userDOToUserDTOs are the same as those of userDOToUserDTO.

Multi-level object conversion

New property CardDO property in UserDO object.

  • CardDO
  @Data
  public class CardDO {
  
     private Long userCardId;
     private String userCardName;
      
  }
Copy the code
  • UserDO
@Data
public class UserDO {

    /** * add */
    private CardDO card;
}
Copy the code
  • UserDTO
@Data
public class UserDTO {
	/** * add */
    // Corresponds to userCardName in CardDO
    private String cardName;
}
Copy the code
  • MapStructConvertertheuserDOToUserDTOModify, addMappingMapping, careful writing, usingUserDOIn thecardProperty call.
    @Mappings({ @Mapping(source = "id",target = "id",ignore = true), @Mapping(source = "birthday", target = "userBirthday",dateFormat = "yyyy-MM-dd HH:mm:ss"), @Mapping(source = "time", target = "userTime",dateFormat = "yyyy-MM-dd"), @Mapping(source = "email", target = "userEmail"), @Mapping(source = "card.userCardName", target = "cardName") } )
    UserDTO userDOToUserDTO(UserDO userDO);
Copy the code
  • test
// Multilevel object conversion
    @Test
    void test3(a){


        UserDO userDo = new UserDO();
        userDo.setId(8888L);
        userDo.setUserName("gongjie");
        userDo.setBirthday(new Date());
        userDo.setTime("2021-05-09");
        userDo.setEmail("[email protected]");

        CardDO cardDO = new CardDO();
        cardDO.setUserCardId(999L);
        cardDO.setUserCardName("ZSYH");
        userDo.setCard(cardDO);
        
        System.out.println("userDo = "+ userDo.toString());
        UserDTO userDTO = MapStructConverter.INSTANCE.userDOToUserDTO(userDo);
        System.out.println("userDTO = "+ userDTO.toString()); } result: userDo = userDo (id=8888, userName=gongjie, birthday=Sun May 09 2209:33 CST 2021, time=2021-05-09, email=99@163.com, card=CardDO(userCardId=999, userCardName=ZSYH))
    
userDTO = UserDTO(id=null, userName=gongjie, userBirthday=2021-05- 092209:33, userTime=Sun May 09 00:00:00 CST 2021, userEmail=99@163.com, cardName=ZSYH)
Copy the code

For one more

MapStruct can map several types of objects to another type, such as converting multiple DO objects to Dtos

  • MapStructConverterIt needs to be modified to add new methodstoUserDTO, pay attention tosourceProperty, called using the name of the method property.
@Mappings({ @Mapping(source = "userDO.birthday", target = "userBirthday",dateFormat = "yyyy-MM-dd HH:mm:ss"), @Mapping(source = "userDO.time", target = "userTime",dateFormat = "yyyy-MM-dd"), @Mapping(source = "userDO.email", target = "userEmail"), @Mapping(source = "cardDO.userCardName", target = "cardName") } )
    UserDTO toUserDTO(UserDO userDO, CardDO cardDO);
Copy the code
  • test
@Test
    void test4(a){
        UserDO userDo = new UserDO();
        userDo.setId(8888L);
        userDo.setUserName("gongjie");
        userDo.setBirthday(new Date());
        userDo.setTime("2021-05-09");
        userDo.setEmail("[email protected]");

        CardDO cardDO = new CardDO();
        cardDO.setUserCardId(999L);
        cardDO.setUserCardName("ZSYH");

        UserDTO userDTO = MapStructConverter.INSTANCE.toUserDTO(userDo,cardDO);
        System.out.println("userDTO = "+ userDTO.toString()); } Output: userDTO = userDTO (id=8888, userName=gongjie, userBirthday=2021-05- 0922:12:04, userTime=Sun May 09 00:00:00 CST 2021, userEmail=99@163.com, cardName=ZSYH)
Copy the code

Updating an existing object

In the previous examples, it was done by something like UserDTO userDOToUserDTO(UserDO UserDO); This is the way to do the transformation. MapStruct provides another way to transform properties in another object. That’s the @mappingTarget annotation.

  • MapStructConverter
   @Mappings({ @Mapping(source = "id",target = "id",ignore = true), @Mapping(source = "birthday", target = "userBirthday",dateFormat = "yyyy-MM-dd HH:mm:ss"), @Mapping(source = "time", target = "userTime",dateFormat = "yyyy-MM-dd"), @Mapping(source = "email", target = "userEmail"), @Mapping(source = "card.userCardName", target = "cardName") } )
    void testMappingTarget(UserDO userDO,@MappingTarget UserDTO userDTO);
Copy the code
  • test
@Test
    void test5(a){
        UserDO userDo = new UserDO();
        userDo.setId(8888L);
        userDo.setUserName("gongjie");
        userDo.setBirthday(new Date());
        userDo.setTime("2021-05-09");
        userDo.setEmail("[email protected]");
        CardDO cardDO = new CardDO();
        cardDO.setUserCardId(999L);
        cardDO.setUserCardName("ZSYH");
        userDo.setCard(cardDO);
        UserDTO userDTO = new UserDTO();
        MapStructConverter.INSTANCE.testMappingTarget(userDo,userDTO);
        System.out.println("userDTO = "+ userDTO.toString()); } result: userDTO = userDTO (id=null, userName=gongjie, userBirthday=2021-05- 0922:24:23, userTime=Sun May 09 00:00:00 CST 2021, userEmail=99@163.com, cardName=ZSYH)
Copy the code

Expression expression

Currently, Java is the only “expression language” supported. Expressions must be given in Java form, and any types referenced in expressions must be given by their fully qualified names. This property cannot be used with source(), defaultValue(), or constant(). Just to give you an example, use scenarios, you’ll see.

  • MapStructConverterIncrease method:testExpressionTo giveuserEmail Concatenation character.
 @Mappings({ @Mapping(source = "id",target = "id",ignore = true), @Mapping(source = "birthday", target = "userBirthday",dateFormat = "yyyy-MM-dd HH:mm:ss"), @Mapping(source = "time", target = "userTime",dateFormat = "yyyy-MM-dd"), @Mapping( target = "userEmail",expression = "java( com.gongj.mapstruct.utils.JoinUtil.join(userDO.getEmail()) )"), @Mapping(source = "card.userCardName", target = "cardName") } )
    UserDTO testExpression(UserDO userDO);
Copy the code
  • JoinUtil
public class JoinUtil {

    public static String join(String oldStr){
        return oldStr + "====expression===="; }}Copy the code
  • test
@Test
    void test6(a){
        UserDO userDo = new UserDO();
        userDo.setId(8888L);
        userDo.setUserName("gongjie");
        userDo.setBirthday(new Date());
        userDo.setTime("2021-05-09");
        userDo.setEmail("[email protected]");

        System.out.println("userDo = "+ userDo.toString());
        UserDTO userDTO = MapStructConverter.INSTANCE.testExpression(userDo);
       System.out.println("userDTO = "+ userDTO.toString());
    }
Copy the code

You need to annotate the method before testing itList<UserDTO> userDOToUserDTOs(List<UserDO> userDO);Otherwise, the following exceptions will occur:

Error: (30.19) Java: fuzzy mapping method finds collection elements mapped to com.gongj.mapstruct.dto.UserDTO userDOToUserDTO(com.gongj.mapstruct.data.UserDO userDO), com.gongj.mapstruct.dto.UserDTO testExpression(com.gongj.mapstruct.data.UserDO userDO).
Copy the code

We can see that the userDOToUserDTO method has the same target and source types as the testExpression method. In the collection conversion example, we already know that the userDOToUserDTOs method calls the userDOToUserDTO method because the target and source types are the same. And now we add a method that matches the userDOToUserDTO target and source types. The userDOToUserDTOs method does not know who to call, so it throws an exception.

  • The source code

You can see in the generated source code that methods are called with fully qualified names.

Of course, if think Java (com) gongj. Mapstruct. Utils. JoinUtil. Join (userDO. GetEmail ())) this kind of writing is too easy to get wrong, can change a kind of writing, is as follows:

  • MapStructConverterModify,@MapperAnnotations add attributesimports, import the target class.
@Mapper(imports = {JoinUtil.class})

 @Mappings({ @Mapping(source = "id",target = "id",ignore = true), @Mapping(source = "birthday", target = "userBirthday",dateFormat = "yyyy-MM-dd HH:mm:ss"), @Mapping(source = "time", target = "userTime",dateFormat = "yyyy-MM-dd"), @Mapping( target = "userEmail",expression = "java( JoinUtil.join(userDO.getEmail()) )"), @Mapping(source = "card.userCardName", target = "cardName") } )
    UserDTO testExpression(UserDO userDO);
Copy the code

Java (JoinUtil.join(Userdo.getemail ())) The result is the same, you go to see!

Custom type conversion methods

And you might find that kind of elegant, but I can do it this way. Call JoinUtil. Join instead. Of course, here is a random example, show how to use.

  • MapStructConverterModify,@MapperAnnotations add attributesuses, import the target class. And add methods:testCustom
@Mapper(imports = {JoinUtil.class},uses = {JoinUtil.class})


 @Mappings({ @Mapping(source = "id",target = "id",ignore = true), @Mapping(source = "birthday", target = "userBirthday",dateFormat = "yyyy-MM-dd HH:mm:ss"), @Mapping(source = "time", target = "userTime",dateFormat = "yyyy-MM-dd"), @Mapping( target = "userEmail"), @Mapping(source = "card.userCardName", target = "cardName") } )
    UserDTO testCustom(UserDO userDO);
Copy the code
  • test
@Test
    void test7(a){
        UserDO userDo = new UserDO();
        userDo.setId(8888L);
        userDo.setUserName("gongjie");
        userDo.setBirthday(new Date());
        userDo.setTime("2021-05-09");
        userDo.setEmail("[email protected]");

        System.out.println("userDo = "+ userDo.toString());
        UserDTO userDTO = MapStructConverter.INSTANCE.testCustom(userDo);
        System.out.println("userDTO = "+ userDTO.toString()); } result: userDo = userDo (id=8888, userName=gongjie, birthday=Mon May 10 20:53:54 CST 2021, time=2021-05-09, email=99@163.com, card=null)
    
userDTO = UserDTO(id=null, userName=gongjie====expression====, userBirthday=2021-05-10 20:53:54, userTime=Sun May 09 00:00:00 CST 2021, userEmail=99@163.com====expression====, cardName=null)
Copy the code

Then you can see that userName and userEmail are both concatenated. Let’s take a look at how the source code does it.

  • The source code

So you can see that all three attributes call the join method, but the userCardName attribute I didn’t assign, so I didn’t go into the if branch block. Why is that? The target type matches the source type, and then matches the join method. All matched properties perform our custom method, a very useful feature that handles properties of the same type uniformly.

Executes the specified custom transformation method

Custom transformations are useful in many cases, but not in certain scenarios. Again, I just want userEmail to concatenate characters. Is there anything else besides expression?

@ the Qualifier annotations

  • First createJoinUtilAnnotationannotations
import org.mapstruct.Qualifier;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Qualifier
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.CLASS)
public @interface JoinUtilAnnotation {
}
Copy the code

Why create an annotation class? That’s because Qualifier annotations can only be annotated on annotations. Pay attention to the guide package!

  • willJoinUtilMake a copy and rename itJoinUtil2
public class JoinUtil2 {

    @JoinUtilAnnotation
    public static String join(String oldStr){
        return oldStr + "====expression===="; }}Copy the code
  • MapStructConverterModify,usesChange the value of the property toJoinUtil2And write another method:testQualifierIn theuserEmailAdded attributes to the mappingqualifiedByAnd point toJoinUtilAnnotationAnnotation.
@Mapper(imports = {JoinUtil.class},uses = {JoinUtil2.class})

  @Mappings({ @Mapping(source = "id",target = "id",ignore = true), @Mapping(source = "birthday", target = "userBirthday",dateFormat = "yyyy-MM-dd HH:mm:ss"), @Mapping(source = "time", target = "userTime",dateFormat = "yyyy-MM-dd"), @Mapping(source="email",target = "userEmail",qualifiedBy = JoinUtilAnnotation.class), @Mapping(source = "card.userCardName", target = "cardName") } )
    UserDTO testQualifier(UserDO userDO);
Copy the code
  • test
  @Test
    void test8(a){
        UserDO userDo = new UserDO();
        userDo.setId(8888L);
        userDo.setUserName("gongjie");
        userDo.setBirthday(new Date());
        userDo.setTime("2021-05-09");
        userDo.setEmail("[email protected]");

        System.out.println("userDo = "+ userDo.toString());
        UserDTO userDTO = MapStructConverter.INSTANCE.testQualifier(userDo);
        System.out.println("userDTO = "+ userDTO.toString()); } result: userDo = userDo (id=8888, userName=gongjie, birthday=Mon May 10 22:16:48 CST 2021, time=2021-05-09, email=99@163.com, card=null)
    
userDTO = UserDTO(id=null, userName=gongjie, userBirthday=2021-05-10 22:16:48, userTime=Sun May 09 00:00:00 CST 2021, userEmail=99@163.com====expression====, cardName=null)
Copy the code
  • The source code

The goal is achieved, but it feels a little complicated to create an annotation. Instead, use expression directly.

@ Named annotation

  • MapStructConverterAdd a strip insidepublicJoinUtil3Class to annotate the method to be executed@NamedAnd specify a name.
class JoinUtil3{

    @Named("join123")
    public static String join(String oldStr){
        return oldStr + "====expression====";
    }
    
	@Named("join1234")
    public static String join1(String oldStr){
        return oldStr + "==== Alternative splicing method ===="; }}Copy the code
  • MapStructConverterModify,usesAttribute points toJoinUtil3, add another method:testNamedIn theuserEmailAdded to mapping relationshipqualifiedByNameProperty, the value of which is equal to@NamedTo determine which method needs to be executed.
@Mapper(imports = {JoinUtil.class},uses = {JoinUtil3.class})

  @Mappings({ @Mapping(source = "id",target = "id",ignore = true), @Mapping(source = "birthday", target = "userBirthday",dateFormat = "yyyy-MM-dd HH:mm:ss"), @Mapping(source = "time", target = "userTime",dateFormat = "yyyy-MM-dd"), @Mapping(source="email",target = "userEmail",qualifiedByName = "join123"), @Mapping(source = "card.userCardName", target = "cardName") } )
    UserDTO testNamed(UserDO userDO);
Copy the code
  • test
	@Test
    void test9(a){
        UserDO userDo = new UserDO();
        userDo.setId(8888L);
        userDo.setUserName("gongjie");
        userDo.setBirthday(new Date());
        userDo.setTime("2021-05-09");
        userDo.setEmail("[email protected]");

        System.out.println("userDo = "+ userDo.toString());
        UserDTO userDTO = MapStructConverter.INSTANCE.testNamed(userDo);
        System.out.println("userDTO = "+ userDTO.toString()); } result: userDo = userDo (id=8888, userName=gongjie, birthday=Mon May 10 22:41:43 CST 2021, time=2021-05-09, email=99@163.com, card=null)
    
userDTO = UserDTO(id=null, userName=gongjie, userBirthday=2021-05-10 22:41:43, userTime=Sun May 09 00:00:00 CST 2021, userEmail=99@163.com====expression====, cardName=null)
Copy the code

Registered with the Spring

ComponentModel = componentModel = componentModel

  • Default: The default, using Mappers. GetMapper (Class) to get the instance object without using the component type

  • Cdi: The generated map is an application-wide CDI bean that can be retrieved via @Inject

  • Spring: An @Component annotation is automatically added to the generated implementation class, which can be injected via Spring’s @Autowired method

  • Jsr330: The generated implementation class will be annotated with @javax.inject.Named annotation, which can be obtained by the @Inject annotation.


@Mapper(imports = {JoinUtil.class},uses = {JoinUtil3.class},componentModel = "spring")
public interface MapStructConverter {

    MapStructConverter INSTANCE = Mappers.getMapper(MapStructConverter.class);
}

Copy the code

But I usually write both. I can use both. Hey hey!

  • The source code

  • test
   @Autowired
    private MapStructConverter mapStructConverterAutowired;

    @Test
    void test9(a){
        UserDO userDo = new UserDO();
        userDo.setId(8888L);
        userDo.setUserName("gongjie");
        userDo.setBirthday(new Date());
        userDo.setTime("2021-05-09");
        userDo.setEmail("[email protected]");

        System.out.println("userDo = "+ userDo.toString());
        UserDTO userDTO = mapStructConverterAutowired.testNamed(userDo);
        System.out.println("userDTO = "+ userDTO.toString()); } result: userDo = userDo (id=8888, userName=gongjie, birthday=Tue May 11 00:07:31 CST 2021, time=2021-05-09, email=99@163.com, card=null)
    
userDTO = UserDTO(id=null, userName=gongjie, userBirthday=2021-05-11 00:07:31, userTime=Sun May 09 00:00:00 CST 2021, userEmail=99@163.Com ==== another concatenation method ====, cardName=null)    
Copy the code

The official documentation

  • If you have any questions or errors in this article, please feel free to comment. If you find this article helpful, please like it and follow it.