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

How to use the mapStruct java bean Mapping tool

2025-02-27 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

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

Today, I will talk to you about how to use the mapStruct java bean mapping tool, many people may not know much about it. In order to make you understand better, the editor has summarized the following for you. I hope you can get something according to this article.

In a mature project, especially in the current distributed system, after there is a separate application subdivision module between applications, DO generally does not allow external dependence. At this time, it is necessary to put DTO for object transmission in the module that provides external interfaces, that is, DO objects are internal, DTO objects are external, DTO can be changed according to business needs, and there is no need to map all the attributes of DO.

This kind of conversion between objects requires a tool specially used to solve the conversion problem. After all, every field get/set will be very troublesome.

MapStruct is such an attribute mapping tool, only need to define a Mapper interface, MapStruct will automatically implement this mapping interface, avoiding complex and tedious mapping implementation.

First, the introduction of maven dependency 1.2.0.Final org.mapstruct mapstruct-jdk8 ${mapstruct.version} org.mapstruct mapstruct-processor ${mapstruct.version} II, basic mapping

Two DO objects, Person and User, are defined here, where user is an attribute of Person and a DTO object PersonDTO.

JavaBean:

@ NoArgsConstructor@AllArgsConstructor@Datapublic class Person {private Long id; private String name; private String email; private Date birthday; private User user;} @ NoArgsConstructor@AllArgsConstructor@Datapublic class User {private Integer age;} @ NoArgsConstructor@AllArgsConstructor@Datapublic class PersonDTO {private Long id; private String name; / * corresponds to Person.user.age * / private Integer age; private String email / * is inconsistent with the field name (birthDay) in DO * / private Date birth; / * extends the field (birthDay) in DO, the form of dateFormat * / private String birthDateFormat; / * * extends the field (birthDay) in DO, and the form of expression * / private String birthExpressionFormat;}

Write a Mapper interface PersonConverter, in which two methods, one is a single entity mapping, the other is List mapping.

If the source object attribute and target object attribute name is the same, will automatically map the corresponding attribute, different need to specify, you can also use format to turn into the type you want, but also support the expression way, you can see that nouns like id, name, email these nouns I did not specify source-target, and birthday-birth specified, conversion format of birthDateFormat plus dateFormat or birthExpressionFormat plus expression, if you do not want to map, you can add an ignore=true.

Mapper (mapping class) of MapSruct:

@ Mapperpublic interface PersonConverter {PersonConverter INSTANCE = Mappers.getMapper (PersonConverter.class) @ Mappings ({@ Mapping (source = "birthday", target = "birth"), @ Mapping (source = "birthday", target = "birthDateFormat", dateFormat = "yyyy-MM-dd HH:mm:ss"), @ Mapping (target = "birthExpressionFormat", expression = "java (org.apache.commons.lang3.time.DateFormatUtils.format (person.getBirthday (),\" yyyy-MM-dd HH:mm:ss\ ")") @ Mapping (source = "user.age", target = "age"), @ Mapping (target = "email", ignore = true)}) PersonDTO domain2dto (Person person) List domain2dto (List people);}

After compiling MapStruct, IDE will compile for us when we compile or start IDE manually, and the corresponding implementation class will be generated under target/classes automatically.

Compile the command mvn compile manually

Attention! The following PersonConverterImpl is generated automatically, not written by yourself!

Public class PersonConverterImpl implements PersonConverter {public PersonConverterImpl () {} public PersonDTO domain2dto (Person person) {if (person = = null) {return null;} else {PersonDTO personDTO = new PersonDTO (); personDTO.setBirth (person.getBirthday ()) If (person.getBirthday ()! = null) {personDTO.setBirthDateFormat ((new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss")) .format (person.getBirthday ());} Integer age = this.personUserAge (person); if (age! = null) {personDTO.setAge (age) } personDTO.setId (person.getId ()); personDTO.setName (person.getName ()); personDTO.setBirthExpressionFormat (DateFormatUtils.format (person.getBirthday (), "yyyy-MM-dd HH:mm:ss")); return personDTO;}} public List domain2dto (List people) {if (people = = null) {return null } else {List list = new ArrayList (people.size ()); Iterator var3 = people.iterator (); while (var3.hasNext ()) {Person person = (Person) var3.next (); list.add (this.domain2dto (person));} return list }} private Integer personUserAge (Person person) {if (person = = null) {return null;} else {User user = person.getUser (); if (user = = null) {return null;} else {Integer age = user.getAge (); return age = = null? Null: age;}

Write a unit test class PersonConverterTest to test it and see how it works.

Public class PersonConverterTest {@ Test public void test () {Person person = new Person (1L, "zhige", "zhige.me@gmail.com", new Date (), new User (1)); PersonDTO personDTO = PersonConverter.INSTANCE.domain2dto (person); assertNotNull (personDTO); assertEquals (personDTO.getId (), person.getId ()); assertEquals (personDTO.getName (), person.getName ()) AssertEquals (personDTO.getBirth (), person.getBirthday ()); String format = DateFormatUtils.format (personDTO.getBirth (), "yyyy-MM-dd HH:mm:ss"); assertEquals (personDTO.getBirthDateFormat (), format); assertEquals (personDTO.getBirthExpressionFormat (), format); List people = new ArrayList (); people.add (person); List personDTOs = PersonConverter.INSTANCE.domain2dto (people); assertNotNull (personDTOs) Three, many to one

MapStruct can map several types of objects to another, such as converting multiple DO objects to DTO.

Example:

Two DO objects Item and Sku, one DTO object SkuDTO

@ NoArgsConstructor@AllArgsConstructor@Datapublic class Item {private Long id; private String title;} @ NoArgsConstructor@AllArgsConstructor@Datapublic class Sku {private Long id; private String code; private Integer price;} @ NoArgsConstructor@AllArgsConstructor@Datapublic class SkuDTO {private Long skuId; private String skuCode; private Integer skuPrice; private Long itemId; private String itemName;}

Create an ItemConverter (mapping) interface, and MapStruct will automatically implement it.

@ Mapperpublic interface ItemConverter {ItemConverter INSTANCE = Mappers.getMapper (ItemConverter.class) @ Mappings ({@ Mapping (source = "sku.id", target = "skuId"), @ Mapping (source = "sku.code", target = "skuCode"), @ Mapping (source = "sku.price", target = "skuPrice"), @ Mapping (source = "item.id", target = "itemId"), @ Mapping (source = "item.title") Target = "itemName")}) SkuDTO domain2dto (Item item, Sku sku) }

Create a test class, which talks about two DO objects, Item and Sku, and maps them to a DTO object SkuDTO

Public class ItemConverterTest {@ Test public void test () {Item item = new Item (1L, "iPhone X"); Sku sku = new Sku (2L, "phone12345", 1000000); SkuDTO skuDTO = ItemConverter.INSTANCE.domain2dto (item, sku); assertNotNull (skuDTO); assertEquals (skuDTO.getSkuId (), sku.getId ()); assertEquals (skuDTO.getSkuCode (), sku.getCode ()) AssertEquals (skuDTO.getSkuPrice (), sku.getPrice ()); assertEquals (skuDTO.getItemId (), item.getId ()); assertEquals (skuDTO.getItemName (), item.getTitle ()) 4. You can add a custom method in the form default PersonDTO personToPersonDTO (Person person) {/ / hand-written mapping logic} / / for example, add the following default Boolean convert2Bool (Integer value) {if (value = = null | | value < 1) {return Boolean.FALSE;} else {return Boolean.TRUE;}} default Integer convert2Int (Boolean value) {if (value = = null) {return null to the PersonConverter. } if (Boolean.TRUE.equals (value)) {return 1;} return 0;} / / Test class PersonConverterTest adds assertTrue (PersonConverter.INSTANCE.convert2Bool (1)); assertEquals ((int) PersonConverter.INSTANCE.convert2Int (true), 1); V. Spring injection mode / / the example I have been writing is the default mode PersonConverter INSTANCE = Mappers.getMapper (PersonConverter.class)

Another common way is to combine with the commonly used framework Spring and add componentModel= "spring" after @ Mapper.

@ Mapper (componentModel= "spring") public interface PersonConverter {@ Mappings ({@ Mapping (source = "birthday", target = "birth"), @ Mapping (source = "birthday", target = "birthDateFormat", dateFormat = "yyyy-MM-dd HH:mm:ss"), @ Mapping (target = "birthExpressionFormat", expression = "java (org.apache.commons.lang3.time.DateFormatUtils.format (person.getBirthday (),\" yyyy-MM-dd HH:mm:ss\ ") @ Mapping (source = "user.age", target = "age"), @ Mapping (target = "email", ignore = true)}) PersonDTO domain2dto (Person person) }

At this point, the test class is changed to the form of spring boot that I use.

@ RunWith (SpringRunner.class) @ SpringBootTest (classes = BaseTestConfiguration.class) public class PersonConverterTest {/ / here assemble the converter @ Autowired private PersonConverter personConverter; @ Test public void test () {Person person = new Person (1L, "zhige", "zhige.me@gmail.com", new Date (), new User (1)); PersonDTO personDTO = personConverter.domain2dto (person); assertNotNull (personDTO) AssertEquals (personDTO.getId (), person.getId ()); assertEquals (personDTO.getName (), person.getName ()); assertEquals (personDTO.getBirth (), person.getBirthday ()); String format = DateFormatUtils.format (personDTO.getBirth (), "yyyy-MM-dd HH:mm:ss"); assertEquals (personDTO.getBirthDateFormat (), format); assertEquals (personDTO.getBirthExpressionFormat (), format) 6. The keyword @ Mapper of MapStruct annotations will MapStruct implement only if this annotation is added to the interface @ Mapper. There is a componentModel attribute in the interface @ Mapper, which mainly specifies the type of the implementation class. Generally, two default are used: by default, you can obtain the instance object spring by Mappers.getMapper (Class): automatically add the annotation @ Component to the implementation class of the interface, and inject @ Mapping: attribute mapping by @ Autowired method. If the source object attribute matches the target object name, it automatically maps the corresponding attribute source: source attribute target: target attribute dateFormat:String to Date date conversion. Through SimpleDateFormat, the value is the date format of SimpleDateFormat ignore: ignore this field @ Mappings: configure multiple @ Mapping@MappingTarget to update existing objects @ InheritConfiguration to inherit the configuration after reading the above Do you have any further understanding of how to use the mapStruct java bean mapping tool? If you want to know more knowledge or related content, please follow the industry information channel, thank you for your support.

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

Internet Technology

Wechat

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

12
Report