MapStruct,对象装载结构工具
Posted 阿昌喜欢吃黄桃
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MapStruct,对象装载结构工具相关的知识,希望对你有一定的参考价值。
MapStruct工具使用
工具名为MapStruct
,用于对象与对象之间的互相转换,避免每一个字段都 get/set 造成麻烦。
MapStruct官网地址: http://mapstruct.org/
如下的演示使用到了Lombok工具
,如果不熟悉的请自行了解,这里就不说了。
一、引包
<!--mapstruct-->
<dependency>
<groupId>org.mapstruct</groupId>
<!-- jdk8以下就使用mapstruct -->
<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、当对象属性相同时
- source源对象
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Person{
private String name;
private Integer age;
}
- target目标对象
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PersonVo{
private String name;
private Integer age;
}
- MapStructMapper接口
import org.mapstruct.Mapper;
@Mapper
public interface PersonMapMapper {
PersonMapMapper INSTANCE = Mappers.getMapper(PersonMapMapper.class);
PersonVo toPersonVo(Person person);
}
- 他会自动在target/classes下生成对应MapStructMapper接口的实现类
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;
}
}
}
- 测试
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、当对象属性不同时
- source源对象
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Person{
private String name;
private Integer age;
}
- target目标对象
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PersonVo{
private String name123;
private Integer age123;
}
- MapStructMapper接口
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接口的实现类
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;
}
}
}
- 测试
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”)==
@Mapper(componentModel = "spring")//通过componentModel属性来指定环境为spirng
public interface PersonMapMapper {
PersonMapMapper INSTANCE = Mappers.getMapper(PersonMapMapper.class);
@Mappings({
@Mapping(source = "name",target = "name123"),
@Mapping(source = "age",target = "age123")
})
PersonVo toPersonVo(Person person);
}
- 生成的Impl文件
发现自动生成了@Component
@Component //发现出现了@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注入使用
// 注入Mapper
@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属性中指定源对象里面属性的对象,用点
来隔开指定
@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
@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属性来实现:
@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;
}
定义转换规则的类:
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属性
用于引用之前定义的转换规则的类:
@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);
}
以上是关于MapStruct,对象装载结构工具的主要内容,如果未能解决你的问题,请参考以下文章