Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Analyze the componentModel attribute of @ Mapper annotation in mybatis

2025-03-29 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article focuses on "analyzing the componentModel attributes of @ Mapper annotations in mybatis". Interested friends may wish to take a look. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn "analyzing the componentModel attributes of @ Mapper annotations in mybatis".

I. preparatory work

1.1. learn about @ Mapper comments

The @ Mapper annotation added from mybatis3.4.0 is intended to stop writing mapper mapping files.

We only need to use annotations on the interfaces defined by the dao layer to write sql statements, such as:

@ Select ("select * from user where name = # {name}") public User find (String name)

The above is a simple use, although simple, but does reflect the advantages of this annotation, at least one less xml file.

So I just want to talk about the componentModel attribute of the @ Mapper annotation, which is used to specify the component type of the automatically generated interface implementation class, which supports four values:

Default: this is the default. Mapstruct does not use any component type, and automatically generated instance objects can be obtained through Mappers.getMapper (Class).

Cdi: the generated mapper is an application-scoped CDI bean and can be retrieved via @ Inject

Spring: an @ Component annotation is automatically added to the generated implementation class, which can be injected through the @ Autowired method of Spring

Jsr330: @ javax.inject.Named and @ Singleton annotations are added to the generated implementation class, which can be obtained through the @ Inject annotation

1.2, dependent package

First, you need to import the dependency package, which is mainly composed of two packages:

Org.mapstruct:mapstruct: contains some necessary annotations, such as @ Mapping. R if we are using a version of JDK higher than 1.8, when we import dependencies in pom, it is recommended to use the coordinate: org.mapstruct:mapstruct-jdk8, which can help us take advantage of some new features of Java8.

Org.mapstruct:mapstruct-processor: an annotation processor that automatically generates mapper based on annotations.

Org.mapstruct mapstruct-jdk8 1.2.0.Final org.mapstruct mapstruct-processor 1.2.0.Final

All right, now that the preparatory work is done, let's see where the wife happens to be.

Second, play a simple game first

2.1. Define entity classes and mapped classes

/ / entity class @ Data @ NoArgsConstructor @ AllArgsConstructor @ Builder public class User {private Integer id; private String name; private String createTime; private LocalDateTime updateTime;} / / mapped class VO1: exactly like entity class @ Data @ NoArgsConstructor @ AllArgsConstructor @ Builder public class UserVO1 {private Integer id; private String name; private String createTime; private LocalDateTime updateTime } / / mapped class VO1: one field less than the entity class @ Data @ NoArgsConstructor @ AllArgsConstructor @ Builder public class UserVO2 {private Integer id; private String name; private String createTime;}

2.2. Define the interface:

When the attributes of the entity class and the mapped object are the same or there are fewer attribute values of the mapped object:

@ Mapper (componentModel = "spring") public interface UserCovertBasic {UserCovertBasic INSTANCE = Mappers.getMapper (UserCovertBasic.class); / * the number of fields is the same, and you can use the tool BeanUtils to achieve a similar effect * @ param source * @ return * / UserVO1 toConvertVO1 (User source); User fromConvertEntity1 (UserVO1 userVO1) / * the number of fields is the same, but the number is small: only more can be converted into fewer, so there is no fromConvertEntity2 * @ param source * @ return * / UserVO2 toConvertVO2 (User source);}

As you can see from the above code, a member variable INSTANCE is declared in the interface, and the parent is to allow the client to access the implementation of the Mapper interface.

2.3. Use

@ RestController public class TestController {@ GetMapping ("convert") public Object convertEntity () {User user = User.builder () .id (1) .name ("Zhang San") .createTime ("2020-04-01 11:05:07") .updateTime (LocalDateTime.now ()) .build () List objectList = new ArrayList (); objectList.add (user); / / use mapstruct UserVO1 userVO1 = UserCovertBasic.INSTANCE.toConvertVO1 (user); objectList.add ("userVO1:" + UserCovertBasic.INSTANCE.toConvertVO1 (user)); objectList.add ("userVO1 converts back to entity class user:" + UserCovertBasic.INSTANCE.fromConvertEntity1 (userVO1)) / / output the conversion result objectList.add ("userVO2:" + "|" + UserCovertBasic.INSTANCE.toConvertVO2 (user)); / / use BeanUtils UserVO2 userVO22 = new UserVO2 (); BeanUtils.copyProperties (user, userVO22); objectList.add ("userVO22:" + "|" + userVO22); return objectList;}}

2.4. View the compilation results

Use the decompilation feature of IDE to view the implementation class UserCovertBasicImpl that automatically generates UserCovertBasic after compilation, as follows:

@ Component public class UserCovertBasicImpl implements UserCovertBasic {public UserCovertBasicImpl () {} public UserVO1 toConvertVO1 (User source) {if (source = = null) {return null;} else {UserVO1 userVO1 = new UserVO1 (); userVO1.setId (source.getId ()); userVO1.setName (source.getName ()); userVO1.setCreateTime (source.getCreateTime ()) UserVO1.setUpdateTime (source.getUpdateTime ()); return userVO1;}} public User fromConvertEntity1 (UserVO1 userVO1) {if (userVO1 = = null) {return null;} else {User user = new User (); user.setId (userVO1.getId ()); user.setName (userVO1.getName ()) User.setCreateTime (userVO1.getCreateTime ()); user.setUpdateTime (userVO1.getUpdateTime ()); return user;}} public UserVO2 toConvertVO2 (User source) {if (source = = null) {return null;} else {UserVO2 userVO2 = new UserVO2 (); userVO2.setId (source.getId ()) UserVO2.setName (source.getName ()); userVO2.setCreateTime (source.getCreateTime ()); return userVO2;}

2.5. Browser to view the results

All right, one process is over, doesn't it feel like a thief?

Moreover, Ah Fan warmly reminds you that if you want to convert a collection, you only need to replace the entity class here with a collection, for example:

List toConvertVOList (List source)

Third, not a simple situation

The above has already given the whole process, I believe you also have a basic understanding of mapstruct, so the next situation we will not show all the code, after all, the space is limited, so go directly to the key code (because the non-critical is the same as the above, )

3.1. Inconsistent types

For entity classes, we still use User; to change the mapping object UserVO3 to:

@ Data @ NoArgsConstructor @ AllArgsConstructor @ Builder public class UserVO3 {private String id; private String name; / / entity class the attribute is String private LocalDateTime createTime; / / entity class and the attribute is LocalDateTime private String updateTime;}

Then the interface we defined needs to be slightly modified:

@ Mappings ({@ Mapping (target = "createTime", expression = "java (com.java.mmzsblog.util.DateTransform.strToDate (source.getCreateTime ())"),}) UserVO3 toConvertVO3 (User source); User fromConvertEntity3 (UserVO3 userVO3)

The expression specified by expression above is as follows:

Public class DateTransform {public static LocalDateTime strToDate (String str) {DateTimeFormatter df = DateTimeFormatter.ofPattern ("yyy-MM-dd HH:mm:ss"); return LocalDateTime.parse ("2018-01-12 17:07:05", df);}}

Looking at the compiled implementation class through the decompilation function of IDE, the result is as follows:

We can see from the figure that the target field createTime is converted using the expression defined in expression at compile time; then you will also find that the updateTime field is also automatically converted from LocalDateTime type to String type.

Summary of A Fan:

When field types are inconsistent, the following types are automatically converted by mapstruct:

1. Basic types and their corresponding packaging types. At this point, mapstruct will unpack automatically. There is no need for artificial treatment.

2. Between the basic type of wrapper type and the string type

In addition to type conversions, we can specify conversions by defining expressions.

3.2. Inconsistent field names

For entity classes, we still use User; to change the mapping object UserVO4 to:

@ Data @ NoArgsConstructor @ AllArgsConstructor @ Builder public class UserVO4 {/ / entity class the attribute name is id private String userId; / / entity class and the attribute name is name private String userName; private String createTime; private String updateTime;}

Then the interface we defined needs to be slightly modified:

@ Mappings ({@ Mapping (source = "id", target = "userId"), @ Mapping (source = "name", target = "userName")}) UserVO4 toConvertVO (User source); User fromConvertEntity (UserVO4 userVO4)

View the compiled implementation class through the decompilation function of IDE, and the compiled result looks like this:

Summary:

When the field names are inconsistent, the corresponding field assignment can be realized after compilation by using the @ Mappings annotation to specify the corresponding relationship.

Obviously, mapstruct helps us assign them to the corresponding position by reading the field name correspondence we configured, which can be said to be quite excellent, but this is only excellent, and the more outstanding ones, please continue to read on:

3.3. The property is an enumerated type

Let's switch to UserEnum for entity classes:

@ Data @ NoArgsConstructor @ AllArgsConstructor @ Builder public class UserEnum {private Integer id; private String name; private UserTypeEnum userTypeEnum;}

Changed by mapping object UserVO5 to:

@ Data @ NoArgsConstructor @ AllArgsConstructor @ Builder public class UserVO5 {private Integer id; private String name; private String type;}

The enumerated objects are:

@ Getter @ AllArgsConstructor public enum UserTypeEnum {Java ("000000", "Java developer"), DB ("001"," database administrator "), LINUX (" 002", "Linux operator"); private String value; private String title;}

Then the interface we define is still defined as usual, and it will not change as soon as it is enumerated:

@ Mapping (source = "userTypeEnum", target = "type") UserVO5 toConvertVO5 (UserEnum source); UserEnum fromConvertEntity5 (UserVO5 userVO5)

View the compiled implementation class through the decompilation function of IDE, and the compiled result looks like this:

Obviously, mapstruct helps us convert enumerated types to strings and assign values to type by enumerating the contents of the types.

At this point, I believe you have a deeper understanding of "analyzing the componentModel properties of @ Mapper annotations in mybatis". You might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report