MapStruct
MapStruct是一个Java工具,它可以自动生成对象之间的映射代码,比如PO、DTO、VO等。MapStruct的作用是简化对象转换的过程,提高代码的可读性和性能,避免手动编写大量的get、set方法。
使用MapStruct的原因是它比BeanUtils等反射方式的工具有很多优势,例如:
- MapStruct是在编译期生成映射代码,而BeanUtils是在运行期通过反射机制获取属性和赋值,因此MapStruct的性能更高,反射会带来额外的开销和性能损耗
- MapStruct生成的代码是普通的Java代码,可以直接查看和修改,而BeanUtils生成的代码是动态的,不易阅读和理解,也不利于重构和维护
- MapStruct支持不同类型之间的自动转换,比如String和Date,而BeanUtils需要手动处理类型转换的逻辑
- MapStruct支持自定义映射规则,比如忽略某些属性,或者使用表达式或方法来映射属性,而BeanUtils只能按照属性名进行映射
如何使用MapStruct
- 导入依赖
<mapstruct.version>1.5.3.Final</mapstruct.version>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${mapstruct.version}</version>
</dependency>
<!--生成實現類依賴-->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</dependency>
- 使用
@Data
public class TestDo {
private String id;
private String name;
private String phone;
private String password;
private String nickname;
private String avatar;
private String age;
private LocalDateTime createTime;
}
@Data
public class TestVo {
private String id;
private String userName;
private int age;
private String createTime;
private List<TestDto> testDtoList;
}
// 此處 mapper 注意別引用錯了 mapcstruct 的 mapper
@Mapper
public interface TestConvert {
TestConvert INSTANCE = Mappers.getMapper(TestConvert.class);
TestDo convert(TestVo testVo);
// 如果字段名稱不同,可以用@Mapping來指定
@Mappings({
@Mapping(source = "name", target = "userName")
})
TestVo convert(TestDo testDo);
List<TestVo> convert(List<TestDo> testDoList);
}
- 编译之后就会生成一个转换实现类
@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2023-12-01T15:41:53+0800",
comments = "version: 1.5.3.Final, compiler: javac, environment: Java 11.0.17 (Amazon.com Inc.)"
)
public class TestConvertImpl implements TestConvert {
@Override
public TestDo convert(TestVo testVo) {
if ( testVo == null ) {
return null;
}
TestDo testDo = new TestDo();
testDo.setId( testVo.getId() );
// 这里类型不用 自动进行了转换
testDo.setAge( String.valueOf( testVo.getAge() ) );
// 日期格式也自动转换 不用手动转换
if ( testVo.getCreateTime() != null ) {
testDo.setCreateTime( LocalDateTime.parse( testVo.getCreateTime() ) );
}
return testDo;
}
@Override
public TestVo convert(TestDo testDo) {
if ( testDo == null ) {
return null;
}
TestVo testVo = new TestVo();
// 自动名称不一样
testVo.setUserName( testDo.getName() );
testVo.setId( testDo.getId() );
if ( testDo.getAge() != null ) {
testVo.setAge( Integer.parseInt( testDo.getAge() ) );
}
if ( testDo.getCreateTime() != null ) {
testVo.setCreateTime( DateTimeFormatter.ISO_LOCAL_DATE_TIME.format( testDo.getCreateTime() ) );
}
return testVo;
}
@Override
public List<TestVo> convert(List<TestDo> testDoList) {
if ( testDoList == null ) {
return null;
}
List<TestVo> list = new ArrayList<TestVo>( testDoList.size() );
for ( TestDo testDo : testDoList ) {
list.add( convert( testDo ) );
}
return list;
}
}
- 具体使用
@RestController
@RequestMapping("/mapstruct")
public class MapstructController {
@GetMapping("test")
public ResultForm convertEntity() {
TestDo testDo = new TestDo().setId("1").setName("zhangsan").setAge("12").setCreateTime(LocalDateTime.now());
TestVo testVo = TestConvert.INSTANCE.convert(testDo);
System.out.println("=========");
return success(testVo);
}
}
// 返回
{
"content": {
"id": "1",
"userName": "zhangsan",
"age": 12,
"createTime": "2023-12-01T15:45:02.099354"
},
"success": true,
"message": "请求成功",
"code": 200
}