mapstruct 是一个bean copy、类型转换的类库,在编译时自动生成生成转换的硬编码代码,执行效率极高
<properties>
<java.version>1.8java.version>
<mapstruct.version>1.5.3.Finalmapstruct.version>
properties>
<dependency>
<groupId>org.mapstructgroupId>
<artifactId>mapstructartifactId>
<version>${mapstruct.version}version>
dependency>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<version>3.8.1version>
<configuration>
<source>${java.version}source>
<target>${java.version}target>
<annotationProcessorPaths>
<path>
<groupId>org.mapstructgroupId>
<artifactId>mapstruct-processorartifactId>
<version>${mapstruct.version}version>
path>
annotationProcessorPaths>
configuration>
plugin>
mapstruct-processor 用插件、依赖均可,上面的插件配置也可以直接换成依赖
<dependency>
<groupId>org.mapstructgroupId>
<artifactId>mapstruct-processorartifactId>
<version>${mapstruct.version}version>
dependency>
二者都是在编译时自动生成代码,mapstruct 会用到 lombok 生成的getter、setter方法,引入时需要配置执行顺序
<properties>
<java.version>1.8java.version>
<lombok.version>1.18.20lombok.version>
<mapstruct.version>1.5.3.Finalmapstruct.version>
properties>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>${lombok.version}version>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.mapstructgroupId>
<artifactId>mapstructartifactId>
<version>${mapstruct.version}version>
dependency>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<version>3.8.1version>
<configuration>
<source>${java.version}source>
<target>${java.version}target>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>${lombok.version}version>
path>
<path>
<groupId>org.mapstructgroupId>
<artifactId>mapstruct-processorartifactId>
<version>${mapstruct.version}version>
path>
annotationProcessorPaths>
configuration>
plugin>
@Mapper //此@Mapper是mapstruct的注解,不是mybatis的注解
public interface UserMapper {
//对象转对象
UserVo bo2Vo(UserBo bo);
//list转list
List<UserVo> bos2Vos(List<UserBo> bos);
//支持多个source参数,source是实体类的会自动取对应的属性字段,source是普通类型的直接使用
OrderRespBo po2OrderRespBo(OrderPo orderPo, Long userId);
//如果target中的某些字段,在多个source中都有,需要指定取哪个source的
@Mapping(source = "orderPo.id", target = "id")
OrderRespBo po2OrderRespBo(OrderPo orderPo, UserPo userPo);
}
//获取mapper实例
UserMapper userMapper = Mappers.getMapper(UserMapper.class);
UserVo userVo = userMapper.bo2Vo(userBo);
List<UserVo> userVos = userMapper.bos2Vos(userBos);
如果修改mapper接口后编译、执行报错,可能是未生成最新的代码实现,可以尝试 mvn clean 后重新编译。
//会作为bean放到spring容器中,也可以使用对应的常量 MappingConstants.ComponentModel.SPRING
@Mapper(componentModel = "spring")
public interface UserMapper {
}
@Resource
private UserMapper userMapper;
其它常见的bean copy框架,往往需要字段名、数据类型相同,才会复制;mapstruct默认字段名相同就会复制,如果字段名相同,但mapstruct编译生成代码时无法实现对应数据类型的转换,编译时会报错,通不过编译
//可以用uses引入需要的类型转换mapper,值是Class[],同名字段会自动使用引入的转换mapper中对应的方法进行转换
@Mapper(uses = {ConvertMapper.class})
public interface UserMapper {
}
import org.mapstruct.Mapper;
import java.util.Date;
/**
* 转换mapper
*/
@Mapper //mapstruct的注解
public interface ConvertMapper {
/**
* Date转时间戳
*
* @param date Date对象
* @return Long
*/
static Long date2Timestamp(Date date) {
return date == null ? null : date.getTime();
}
/**
* 时间戳转Date
*
* @param timestamp 时间戳
* @return Date
*/
static Date timestamp2Date(Long timestamp) {
return timestamp == null ? null : new Date(timestamp);
}
/**
* Integer 转 Boolean
*
* @param intValue 整型数据
* @return Boolean
*/
static Boolean int2Boolean(Integer intValue) {
if (intValue == null || intValue == 0) {
return Boolean.FALSE;
}
return Boolean.TRUE;
}
/**
* Boolean 转 Integer
*
* @param boolValue 布尔类型数据
* @return Integer
*/
static Integer bool2Integer(Boolean boolValue) {
if (boolValue == null || !boolValue) {
return 0;
}
return 1;
}
}
@Mapper
public interface UserMapper {
//分别指定参数、目标类中的字段,可同时标注多个 @Mapping
@Mapping(source = "tel", target = "phoneNumber")
@Mapping(source = "name", target = "username")
UserVo bo2Vo(UserBo bo);
//同时使用多个时,也可以放在 @Mappings 中
@Mappings({
@Mapping(source = "tel", target = "phoneNumber"),
@Mapping(source = "name", target = "username")
})
UserVo bo2Vo(UserBo bo);
//只有1个参数时可以不带参数名,有多个参数时要带上参数名
@Mapping(source = "userBo.userId", target = "userId")
@Mapping(source = "orderBo.amount", target = "orderAmount")
UserVo bo2Vo(UserBo userBo, OrderBo orderBo);
}
可以给target字段指定默认值,当target为null(即source为null)时,target会自动取默认值
//source属性不是必需的,缺省时默认取target的值
@Mapping(target = "username", defaultValue = "")
@Mapping(source = "name", target = "username", defaultValue = "")