MapStruct的使用


 

mapstruct 是一个bean copy、类型转换的类库,在编译时自动生成生成转换的硬编码代码,执行效率极高

pom.xml

在不使用 lombok 的情况下使用 mapstruct
<properties>
    <java.version>1.8</java.version>
    <mapstruct.version>1.5.3.Final</mapstruct.version>
</properties>

<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct</artifactId>
    <version>${mapstruct.version}</version>
</dependency>

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.8.1</version>
    <configuration>
        <source>${java.version}</source>
        <target>${java.version}</target>
        <annotationProcessorPaths>
            <!-- 引入mapstruct-processor -->
            <path>
                <groupId>org.mapstruct</groupId>
                <artifactId>mapstruct-processor</artifactId>
                <version>${mapstruct.version}</version>
            </path>
        </annotationProcessorPaths>
    </configuration>
</plugin>

mapstruct-processor 用插件、依赖均可,上面的插件配置也可以直接换成依赖

<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-processor</artifactId>
	<version>${mapstruct.version}</version>
</dependency>

 

同时使用 lombok、mapstruct

二者都是在编译时自动生成代码,mapstruct 会用到 lombok 生成的getter、setter方法,引入时需要配置执行顺序

<properties>
    <java.version>1.8</java.version>
    <lombok.version>1.18.20</lombok.version>
    <mapstruct.version>1.5.3.Final</mapstruct.version>
</properties>

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>${lombok.version}</version>
    <optional>true</optional>
</dependency>
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct</artifactId>
    <version>${mapstruct.version}</version>
</dependency>

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.8.1</version>
    <configuration>
        <source>${java.version}</source>
        <target>${java.version}</target>
        <annotationProcessorPaths>
            <!-- 先执行lombok-processor -->
            <path>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
            </path>
            <!-- 再执行mapstruct-processor -->
            <path>
                <groupId>org.mapstruct</groupId>
                <artifactId>mapstruct-processor</artifactId>
                <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注入

//会作为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;
    }

}
  • 不局限于jdk自带的数据类型转换,也可以写自定义的实体类之间的转换
  • 生成代码时,mapstruct会自动使用当前mapper中已存在的方法、uses引入的mapper中的方法

 

自定义字段映射

@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 = "")
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值