工具名为`MapStruct`,用于对象与对象之间的互相转换,避免每一个字段都 get/set 造成麻烦。
MapStruct官网地址: http://mapstruct.org/
如下的演示使用到了Lombok工具
,如果不熟悉的请自行了解,这里就不说了。
一、引包
1 2 3 4 5 6 7 8 9 10 11 12
| <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-jdk8</artifactId> <version>1.2.0.Final</version> </dependency> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>1.2.0.Final</version> </dependency>
|
二、demo
1、当对象属性==相同==时
1 2 3 4 5 6 7 8
| @Data @NoArgsConstructor @AllArgsConstructor @Builder public class Person{ private String name; private Integer age; }
|
1 2 3 4 5 6 7
| @Data @NoArgsConstructor @AllArgsConstructor public class PersonVo{ private String name; private Integer age; }
|
1 2 3 4 5 6 7 8
| import org.mapstruct.Mapper;
@Mapper public interface PersonMapMapper { PersonMapMapper INSTANCE = Mappers.getMapper(PersonMapMapper.class);
PersonVo toPersonVo(Person person); }
|
- 他会自动在target/classes下生成对应MapStructMapper接口的实现类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class PersonMapMapperImpl implements PersonMapMapper { public PersonMapMapperImpl() { }
public PersonVo toPersonVo(Person person) { if (person == null) { return null; } else { PersonVo personVo = new PersonVo(); personVo.setName(person.getName()); personVo.setAge(person.getAge()); return personVo; } } }
|
1 2 3 4 5 6 7
| public class test { public static void main(String[] args) { Person person = Person.builder().age(1).name("阿昌").build(); PersonVo personVo = PersonMapMapper.INSTANCE.toPersonVo(person); System.out.println(personVo); } }
|
2、当对象属性==不同==时
1 2 3 4 5 6 7 8
| @Data @NoArgsConstructor @AllArgsConstructor @Builder public class Person{ private String name; private Integer age; }
|
1 2 3 4 5 6 7
| @Data @NoArgsConstructor @AllArgsConstructor public class PersonVo{ private String name123; private Integer age123; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.Mappings; import org.mapstruct.factory.Mappers;
@Mapper public interface PersonMapMapper { PersonMapMapper INSTANCE = Mappers.getMapper(PersonMapMapper.class);
@Mappings({ @Mapping(source = "name",target = "name123"), @Mapping(source = "age",target = "age123") }) PersonVo toPersonVo(Person person); }
|
- 他会自动在target/classes下生成对应MapStructMapper接口的实现类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| package com.achang.fmService.testMapStruct;
public class PersonMapMapperImpl implements PersonMapMapper { public PersonMapMapperImpl() { }
public PersonVo toPersonVo(Person person) { if (person == null) { return null; } else { PersonVo personVo = new PersonVo(); personVo.setName123(person.getName()); personVo.setAge123(person.getAge()); return personVo; } } }
|
1 2 3 4 5 6 7
| public class test { public static void main(String[] args) { Person person = Person.builder().age(1).name("阿昌").build(); PersonVo personVo = PersonMapMapper.INSTANCE.toPersonVo(person); System.out.println(personVo); } }
|
3、如何结合springIoc容器?
添加==@Mapper(componentModel = “spring”)==
1 2 3 4 5 6 7 8 9 10
| @Mapper(componentModel = "spring") public interface PersonMapMapper { PersonMapMapper INSTANCE = Mappers.getMapper(PersonMapMapper.class);
@Mappings({ @Mapping(source = "name",target = "name123"), @Mapping(source = "age",target = "age123") }) PersonVo toPersonVo(Person person); }
|
发现自动生成了@Component
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @Component public class PersonMapMapperImpl implements PersonMapMapper { public PersonMapMapperImpl() { }
public PersonVo toPersonVo(Person person) { if (person == null) { return null; } else { PersonVo personVo = new PersonVo(); personVo.setName123(person.getName()); personVo.setAge123(person.getAge()); return personVo; } } }
|
下次就可以直接通过@Autowired注入使用
1 2 3 4 5 6 7 8 9 10
| @Autowired private PersonMapMapper mapper;
@GetMapping("/test") public String test() { Person person = new Person("阿昌", 1); PersonVo personVo = mapper.toPersonVo(person); return personVo.toString(); }
|
4、如果对象里面还有对象的情况,和多参数情况,和传入参数情况
通过Mapping中source属性中指定源对象里面属性的对象,用点
来隔开指定
1 2 3 4 5 6
| @Mappings({ @Mapping(source = "user.id", target = "userId"), // 指定对象里面的属性 @Mapping(source = "role.name", target = "roleName"), // 指定对象里面的属性 @Mapping(source = "myRoleDesc", target = "myRoleDesc") //使用参数既可 }) UserRoleDto toUserRoleDto(User user, Role role,String myRoleDesc);
|
5、更新对象属性
MapStruct提供了另外一种方式来更新一个对象中的属性。@MappingTarget
1 2 3 4 5 6
| @Mappings({ @Mapping(source = "id", target = "userId"), @Mapping(source = "username", target = "name"), @Mapping(source = "role.roleName", target = "roleName") }) void update(User user, @MappingTarget UserRoleDto userRoleDto);
|
通过@MappingTarget
来指定目标类是谁(谁的属性需要被更新)。@Mapping还是用来定义属性对应规则。
上面的演示就是说,从user对象中的id属性,更新到userRoleDto对象中的userId属性
6、自定义类型转换
有时候,在对象转换的时候可能会出现这样一个问题,就是源对象中的类型是Boolean类型,而目标对象类型是String类型,这种情况可以通过@Mapper的uses属性来实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| @Data @NoArgsConstructor @AllArgsConstructor public class Customer { private Long id; private String name; private Boolean isDisable; }
@Data public class CustomerDto { private Long id; private String customerName; private String disable; }
|
定义转换规则的类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class BooleanStrFormat { public String toStr(Boolean isDisable) { if (isDisable) { return "Y"; } else { return "N"; } } public Boolean toBoolean(String str) { if (str.equals("Y")) { return true; } else { return false; } } }
|
定义Mapper,@Mapper( uses = { BooleanStrFormat.class})
,注意,这里的users属性
用于引用之前定义的转换规则的类:
1 2 3 4 5 6 7 8 9 10 11
| @Mapper( uses = { BooleanStrFormat.class}) public interface CustomerMapper {
CustomerMapper INSTANCES = Mappers.getMapper(CustomerMapper.class);
@Mappings({ @Mapping(source = "name", target = " customerName"), @Mapping(source = "isDisable", target = "disable") }) CustomerDto toCustomerDto(Customer customer); }
|