SpringBoot2.3整合MapStruct实现Java bean映射

1. 概述

MapStruct 是一个代码生成器,它基于约定优于配置方法极大地简化了 Java bean 类型之间映射的实现。方便pojo、vo、dto与实体类之间的相互转换。更多详情请参阅官网
优缺点

  • MapStruct在编译的时候生成映射的代码,如果有错误会在编译时就发现
  • 底层使用get/set方法,而非反射方式,执行时效率更快
  • 可以实现深拷贝,修改新对象时不会对老对象产生影响
  • 类型更加安全,只能映射相互映射的对象和属性,可以进行自定义的类型和字段映射
  • 需要额外新增一个接口或者抽象类

2. 引入核心依赖

<properties>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
    <mapstruct.version>1.4.2.Final</mapstruct.version>
    <lombok.version>1.18.20</lombok.version>
    <lombok-mapstruct.version>0.2.0</lombok-mapstruct.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct</artifactId>
        <version>${mapstruct.version}</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <annotationProcessorPaths>
                    <path>
                        <groupId>org.mapstruct</groupId>
                        <artifactId>mapstruct-processor</artifactId>
                        <version>${mapstruct.version}</version>
                    </path>
                    <path>
                        <groupId>org.projectlombok</groupId>
                        <artifactId>lombok</artifactId>
                        <version>${lombok.version}</version>
                    </path>
                    <path>
                        <groupId>org.projectlombok</groupId>
                        <artifactId>lombok-mapstruct-binding</artifactId>
                        <version>${lombok-mapstruct.version}</version>
                    </path>
                </annotationProcessorPaths>
            </configuration>
        </plugin>
    </plugins>
</build>

3. 新建实体类和dto对象

@Getter
@Setter
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class SysUserInfo {
    
    

    /**
     * 主键ID
     */
    private Long id;

    /**
     * 用户名称
     */
    private String userName;

    /**
     * 性别0:男;1:女;2:未知
     */
    private SexEnum sex;

    /**
     * 邮箱
     */
    private String email;

    /**
     * 手机号
     */
    private String phonenumber;

    /**
     * 头像
     */
    private String avatar;

    /**
     * 状态0:正常;1:停用
     */
    private Integer status;

    /**
     * 薪水
     */
    private BigDecimal salary;

    /**
     * 创建者
     */
    private String createUser;

    /**
     * 创建时间
     */
    private LocalDateTime createTime;

    /**
     * 更新者
     */
    private String updateUser;
}
@Getter
@Setter
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class UserVo {
    
    

    /**
     * 主键ID
     */
    private String id;

    /**
     * 用户名称
     */
    private String userName;

    /**
     * 密码
     */
    private String password;

    /**
     * 性别0:男;1:女;2:未知
     */
    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("[email protected]")
                .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:用于自定义命名

更多使用方法可参阅官网文档
更多示例可参阅官网示例

猜你喜欢

转载自blog.csdn.net/liu320yj/article/details/121470717