1.为什么MapStruct代替BeanUtils.copyProperties ()
第一:因为BeanUtils 采用反射的机制动态去进行拷贝映射,特别是Apache的BeanUtils的性能很差,而且并不支持所有数据类型的拷贝,虽然使用较为方便,但是强烈不建议使用;
第二:虽然Spring的BeanUtils类所带方法比Apache的的BeanUtils的性能好点,但是性能还是很差,没办法跟mapStruct相对比,使用方便但是也不建议使用(性能不好会很卡机);
第三:MapStruct采用的是单纯的 get 和 set 方法,但是使用相对BeanUtils来说要多一个步骤,推荐使用,性能很好。
2.MapStruct的使用步骤
官网:Installation – MapStruct(个人始终坚持学一个东西先从官网了解开始)
1.添加依赖:
<properties>
<org.mapstruct.version>1.5.5.Final</org.mapstruct.version>
</properties>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
2.准备好要转换的类:AccountDTO属性值赋给Accout
AccountDTO:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class AccountDTO {
private static final long serialVersionUID = 1L;
@NotBlank
private String userName;
@NotNull
private Integer age;
private String password;
private String phone;
@Email
private String email;
}
Account为:
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(value = "tb_account")
public class Account {
private static final long serialVersionUID = 1L;
private String accountId;
private String userName;
private String password;
private String phone;
private String email;
private Integer age;
private Date birthday;
}
3.写一个Interface接口:
@Mapper
public interface AccountConvertor {
AccountConvertor ACCOUNT = Mappers.getMapper(AccountConvertor.class);
/**
* 将账户类AccountDTO的值赋给为Account
* @param accountDTO
* @return
*/
Account convertAccount(AccountDTO accountDTO);
}
4.Interface接口的使用:
上述是对于AccountDTO和Account对应的属性名以及属性的数据类型完全一致的情况可执行。
但是如果属性名或者数据类型对不上的话比如如下:
要解决问题需按以下来:
第一步:继续添加插件:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source> <!-- depending on your project -->
<target>1.8</target> <!-- depending on your project -->
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
<!-- other annotation processors -->
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
2.改良Interface接口:
重新测试即可。
若上述运行报错说找不到AccountDTO中的属性birthday,则将添加的插件换成如下:
<properties>
<org.mapstruct.version>1.5.5.Final</org.mapstruct.version>
<org.mybatis.flex.version>1.7.7</org.mybatis.flex.version>
<org.lombok.version>1.18.28</org.lombok.version>
<org.lombok.mapstruct.binding.version>1.18.28</org.lombok.mapstruct.binding.version>
</properties>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source> <!-- depending on your project -->
<target>1.8</target> <!-- depending on your project -->
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${org.lombok.version}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>${org.lombok.mapstruct.binding.version}</version>
</path>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
<path>
<groupId>com.mybatis-flex</groupId>
<artifactId>mybatis-flex-processor</artifactId>
<version>${org.mybatis.flex.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
3.扩展
查看原理:在使用的位置进行如下操作:
操作后进入具体的实现方式(下图文件系统自动生成,不需要手动创建):如下:
也就是:
更新已有实体的部分数据:
但是在很多情况下,我只需要更新已有Account的某些字段,而这些字段放在AccountDto里面的话,可以如下:在接口方法入参中添加另一个参数并用注解@MappingTarget:
使用方法:
查看文件AccountConvertorImpl具体实现如下: