MapStruct 是一个代码生成器,它基于约定优于配置方法极大地简化了 Java bean 类型之间映射的实现。方便pojo、vo、dto与实体类之间的相互转换。更多详情请参阅官网
优缺点
- MapStruct在编译的时候生成映射的代码,如果有错误会在编译时就发现
- 底层使用get/set方法,而非反射方式,执行时效率更快
- 可以实现深拷贝,修改新对象时不会对老对象产生影响
- 类型更加安全,只能映射相互映射的对象和属性,可以进行自定义的类型和字段映射
- 需要额外新增一个接口或者抽象类
3. 新建实体类和dto对象8 8 1.4.2.Final 1.18.20 0.2.0 org.springframework.boot spring-boot-starter-web org.mapstruct mapstruct ${mapstruct.version} org.projectlombok lombok provided org.springframework.boot spring-boot-starter-test test org.apache.maven.plugins maven-compiler-plugin 3.8.1 1.8 1.8 org.mapstruct mapstruct-processor ${mapstruct.version} org.projectlombok lombok ${lombok.version} org.projectlombok lombok-mapstruct-binding ${lombok-mapstruct.version}
@Getter
@Setter
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class SysUserInfo {
private Long id;
private String userName;
private SexEnum sex;
private String email;
private String phonenumber;
private String avatar;
private Integer status;
private BigDecimal salary;
private String createUser;
private LocalDateTime createTime;
private String updateUser;
}
@Getter
@Setter
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class UserVo {
private String id;
private String userName;
private String password;
private String sex;
private String email;
private String phone;
private String avatar;
private String status;
private String salary;
private String createUser;
private String createTime;
private String updateUser;
private String updateTime;
}
4. 新建映射接口
@Mapper
public interface SysUserInfoMapper {
SysUserInfoMapper INFO_MAPPER = Mappers.getMapper(SysUserInfoMapper.class);
@Mapping(target = "id", defaultValue = "1")
@Mapping(target = "password", ignore = true)
@Mapping(source = "phonenumber", target = "phone")
@Mapping(source = "sex.value", target = "sex")
@Mapping(target = "status", constant = "正常")
@Mapping(target = "salary", numberFormat = "#.00")
@Mapping(target = "createTime", dateFormat = "yyyy-MM-dd HH:mm:ss")
@Mapping(source = "userInfo", target = "updateTime", qualifiedByName = "now")
UserVo map(SysUserInfo userInfo);
@Named("now")
default LocalDateTime now(Object source) {
return LocalDateTime.now();
}
}
5. 测试
@SpringBootTest
public class MapStructApplicationTest {
@Test
void userTest() {
SysUserInfo userInfo = SysUserInfo.builder()
.id(1L)
.userName("zhangsan")
.sex(SexEnum.MALE)
.email("zhangsan@163.com")
.status(0)
.salary(new BigDecimal(12000))
.phonenumber("13898767890")
.createUser("admin")
.createTime(LocalDateTime.now())
.updateUser("admin")
.build();
UserVo userVo = SysUserInfoMapper.INFO_MAPPER.map(userInfo);
System.out.println(userVo.toString());
Assertions.assertNotNull(userVo);
}
}
6. 扩展
Mapper接口可以使用工厂方法注入,也可以使用依赖注入方式,如下所示:
@Mapper(componentModel = "spring")
public interface SysUserInfoMapper {
@Mapping(target = "id", defaultValue = "1")
@Mapping(target = "password", ignore = true)
@Mapping(source = "phonenumber", target = "phone")
@Mapping(source = "sex.value", target = "sex")
@Mapping(target = "status", constant = "正常")
@Mapping(target = "salary", numberFormat = "#.00")
@Mapping(target = "createTime", dateFormat = "yyyy-MM-dd HH:mm:ss")
@Mapping(source = "userInfo", target = "updateTime", qualifiedByName = "now")
UserVo map(SysUserInfo userInfo);
@Named("now")
default LocalDateTime now(Object source) {
return LocalDateTime.now();
}
}
使用时只需要按照普通接口注入就行
@Mapping注解属性值解释
source:数据源
target:目标对象
defaultValue:用于设置默认值
constant:用于设置常量
numberFormat:用于设置数据格式
dateFormat:用于设置日期格式
qualifiedByName:用于自定义命名
更多使用方法可参阅官网文档
更多示例可参阅官网示例



