基本介绍
MapStruct工具类能实现不同对象之间的转换,类似于BeanUtils。
简单使用-不同对象之间的属性名相同
MapStruct工具类所需依赖:
<!--添加依赖-->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.5.1.Final</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.1.Final</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>1.5.1.Final</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.26</version>
</dependency>
<build>
<!--配合Lombok使用需要添加插件-->
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.1.Final</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.26</version>
</path>
<!-- additional annotation processor required as of Lombok 1.18.16 -->
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>0.2.0</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
- 定义不同的实体
// Dog类和DogVo类的定义
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Dog {
private String name;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class DogVo {
private String name;
}
- 自定义一个转换器接口,实现不同对象之间的转换
/**
* 注意:@Mapper注解是mapstruct包下的
* 如果希望将该Bean注入到Spring容器,可以将该注解的componentModel属性置为spring,可以实现自动注入
*/
@Mapper
public interface Dog2DogVoConvert {
// 使用Mappers(mapstruct包下的一个工厂对象)根据接口的class对象获取一个转换器
// 该对象是mapstruct自动帮我们实现接口的实现类对象
Dog2DogVoConvert INSTANCE = Mappers.getMapper(Dog2DogVoConvert.class);
// 定义一个方式,其功能为将一个对象转换为另一个对象
DogVo dog2DogVo(Dog dog);
}
- 测试
public class SimpleTest {
/**
* 简单测试
*/
@Test
public void testSimpleDemoConvert() {
// 定义一个Dog对象
Dog dog = new Dog("Jack");
// 使用mapstruct生成的实现类完成对象的转换
DogVo dogVo = Dog2DogVoConvert.INSTANCE.dog2DogVo(dog);
// 输出mapstruct生成的实现类的class类型,发现是接口的实现类,默认名称为:接口名Impl
System.out.println(Dog2DogVoConvert.INSTANCE.getClass());
// 输出转换后的数据,发现确实被转换了
System.out.println("dogVo = " + dogVo);
}
}
输出结果:
class com.lerqe.convert.Dog2DogVoConvertImpl
dogVo = DogVo(name=Jack)
进阶使用-不同对象之间的属性名不同
当要转换的对象中的某个属性和原来的对象属性名称不一致时,可以使用@Mapping
注解实现属性的映射。
当要转换的对象中的多个属性和原来的的对象属性名称不一致时,可以使用Mappings+@Mapping
注解来实现多个属性的映射
- 定义不同的实体
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class StorageSource {
private Integer id;
private String name;
private List record;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ResponseEntity {
private Integer rid;
private String rname;
private List items;
}
- 自定义一个转换器接口,实现不同对象之间的转换
@Mapper
public interface StorageSource2ResponseEntityConvert {
// 使用Mappers(mapstruct包下的一个工厂对象)根据接口的class对象获取一个转换器
// 该对象是mapstruct自动帮我们实现接口的实现类对象
StorageSource2ResponseEntityConvert INSTANCE = Mappers.getMapper(StorageSource2ResponseEntityConvert.class);
// 定义一个方式,其功能为将一个对象转换为另一个对象
// 使用@Mapping注解可以完成单个属性名不一致的转换,使用@Mappings+@Mapping注解可以实现多个属性名不一致的转换
@Mappings({
@Mapping(source = "id",target = "rid"), // source代表原属性名,target代表要转换的属性名
@Mapping(source = "name",target = "rname"),
@Mapping(source = "record",target = "items")
})
// 定义一个方式,其功能为将一个对象转换为另一个对象
ResponseEntity storageSource2ResponseEntity(StorageSource storageSource);
}
- 测试
/**
* 属性名不一致如何转换
*/
@Test
public void testFieldConvert() {
List list = new ArrayList<>();
Collections.addAll(list,"a","b","c");
StorageSource jack = new StorageSource(1, "Jack", list);
ResponseEntity responseEntity = StorageSource2ResponseEntityConvert.INSTANCE.storageSource2ResponseEntity(jack);
System.out.println("responseEntity = " + responseEntity);
}
输出结果:
responseEntity = ResponseEntity(rid=1, rname=Jack, items=[a, b, c])
进阶使用-集合的转换
当要转换的对象是一个集合且集合中泛型指定的对象属性名不一致时,我们数据额外添加一个方法,实现集合中泛型指定的对象的转换。
- 定义不同实体
// 集合中存储的对象
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Dog {
private String name;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Cat {
private String catName;
}
// 要进行转换的对象
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class StorageSource {
private Integer id;
private String name;
private List<Dog> record; // 指定泛型
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ResponseEntity {
private Integer rid;
private String rname;
private List<Cat> items; // 指定泛型
}
- 自定义一个转换器接口,实现不同对象之间的转换
/**
* 注意:@Mapper注解是mapstruct包下的
* 如何希望将该Bean注入到Spring容器,可以将该注解的componentModel属性置为spring,可以实现自动注入
*/
@Mapper
public interface StorageSource2ResponseEntityConvert {
// 使用Mappers(mapstruct包下的一个工厂对象)根据接口的class对象获取一个转换器
// 该对象是mapstruct自动帮我们实现接口的实现类对象
StorageSource2ResponseEntityConvert INSTANCE = Mappers.getMapper(StorageSource2ResponseEntityConvert.class);
// 定义一个方式,其功能为将一个对象转换为另一个对象
// 使用@Mapping注解可以完成单个属性名不一致的转换,使用@Mappings+@Mapping注解可以实现多个属性名不一致的转换
@Mappings({
@Mapping(source = "id",target = "rid"),
@Mapping(source = "name",target = "rname"),
@Mapping(source = "record",target = "items")
})
// 定义一个方式,其功能为将一个对象转换为另一个对象
ResponseEntity storageSource2ResponseEntity(StorageSource storageSource);
// 定义一个方式,其功能为将一个对象转换为另一个对象
// 如何集合中存储的对象不一致时,使用该方法进行转换
@Mapping(source = "name",target = "catName")
Cat dog2Cat(Dog dog);
}
- 测试
@Test
public void testFieldConvert() {
List<Dog> list = new ArrayList<>();
Collections.addAll(list,new Dog("a"),new Dog("b"),new Dog("c"));
StorageSource jack = new StorageSource(1, "Jack", list);
ResponseEntity responseEntity = StorageSource2ResponseEntityConvert.INSTANCE.storageSource2ResponseEntity(jack);
System.out.println("responseEntity = " + responseEntity);
}
输出结果:
responseEntity = ResponseEntity(rid=1, rname=Jack, items=[Cat(catName=a), Cat(catName=b), Cat(catName=c)])