实体属性映射框架mapstruct

1. 框架介绍

mapstruct框架是一种实体类间的映射框架,能够通过JAVA注解的形式将一个实体类的属性安全的赋值给另一个实体类。通过一系列注解可以定义实体类属性之间的映射关系,mapstruct会在编译期间生成映射实现类,而非通过反射的方式进行实体类赋值。

(1)安全性高,编译期就实现源对象到目标对象的映射,如果编译器能够通过,运行期就不会报错。

(2)速度快,运行期间直接调用实现类的方法,不会在运行期间使用反射进行转化。

2. 项目依赖

  • 实体Getter和Setter方法生成依赖
  • 实体映射依赖
  • JSON依赖
  • 单元测试依赖
<dependencies>
    <dependency>
        <groupId>org.projectlombokgroupId>
        <artifactId>lombokartifactId>
        <version>1.18.28version>
    dependency>

    <dependency>
        <groupId>org.mapstructgroupId>
        <artifactId>mapstructartifactId>
        <version>1.4.2.Finalversion>
    dependency>

    <dependency>
        <groupId>org.mapstructgroupId>
        <artifactId>mapstruct-processorartifactId>
        <version>1.4.2.Finalversion>
    dependency>

    <dependency>
        <groupId>com.alibabagroupId>
        <artifactId>fastjsonartifactId>
        <version>1.2.83version>
    dependency>

    <dependency>
        <groupId>junitgroupId>
        <artifactId>junitartifactId>
        <version>4.13.2version>
        <scope>testscope>
    dependency>
dependencies>

3. 基础映射

单一实体映射 + 批量实体映射

3.1 持久层实体类

@Getter
@Setter
public class SysUserDO implements Serializable {

    /**
     * 用户编号
     */
    private Long userId;

    /**
     * 用户姓名
     */
    private String realName;

    /**
     * 用户年龄
     */
    private Integer age;

    /**
     * 用户性别
     */
    private Boolean sex;

    /**
     * 出生日期
     */
    private LocalDate birthday;

    @Override
    public String toString() {
        return JSON.toJSONString(this);
    }
}

3.2 业务层实体类

@Getter
@Setter
public class SysUserBO {

    /**
     * 用户编号
     */
    private Long userId;

    /**
     * 用户姓名
     */
    private String realName;

    /**
     * 用户年龄
     */
    private Integer age;

    /**
     * 用户性别
     */
    private Boolean sex;

    /**
     * 出生日期
     */
    private LocalDate birthday;

    @Override
    public String toString() {
        return JSON.toJSONString(this);
    }
}

3.3 转换层接口

@Mapper
public interface SysUserTransfer {

    /**
     * 实体转换
     *
     * @param user 持久层-系统用户实体
     * @return 业务层-系统用户实体
     */
    @Mappings({
       @Mapping(source = "userId", target = "userId"),
       @Mapping(source = "realName", target = "realName"),
       @Mapping(source = "age", target = "age"),
       @Mapping(source = "sex", target = "sex"),
       @Mapping(source = "birthday", target = "birthday")
    })
    SysUserBO transfer(SysUserDO user);

    /**
     * 实体列表转换
     *
     * @param users 持久层-系统用户实体列表
     * @return 业务层-系统用户实体列表
     */
    @Mappings({
        @Mapping(source = "userId", target = "userId"),
        @Mapping(source = "realName", target = "realName"),
        @Mapping(source = "age", target = "age"),
        @Mapping(source = "sex", target = "sex"),
        @Mapping(source = "birthday", target = "birthday")
    })
    List<SysUserBO> transfers(List<SysUserDO> users);
}

3.4 接口测试类

public class SysUserTransferTest {

    @Test
    public void transfer() {
        // 1.构造持久层系统用户实例
        SysUserDO sysUserDO = new SysUserDO();
        sysUserDO.setUserId(10001L);
        sysUserDO.setRealName("亡灵天灾");
        sysUserDO.setAge(26);
        sysUserDO.setSex(true);
        sysUserDO.setBirthday(LocalDate.now());

        // 2.获取转换接口实例并转换实体
        SysUserTransfer sysUserTransfer = Mappers.getMapper(SysUserTransfer.class);
        SysUserBO sysUserBO = sysUserTransfer.transfer(sysUserDO);

        // 3.打印实体内容
        System.out.println("sysUserDO = " + sysUserDO);
        System.out.println("sysUserBO = " + sysUserBO);
    }

    @Test
    public void transfers() {
        // 1.批量构造持久层系统用户实例
        List<SysUserDO> sysUserDOS = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            SysUserDO sysUserDO = new SysUserDO();
            sysUserDO.setUserId(Long.valueOf(10000 + i));
            sysUserDO.setRealName("亡灵天灾" + i);
            sysUserDO.setAge(26);
            sysUserDO.setSex(true);
            sysUserDO.setBirthday(LocalDate.now());
            sysUserDOS.add(sysUserDO);
        }

        // 2.获取转换接口实例并批量转换实体
        SysUserTransfer sysUserTransfer = Mappers.getMapper(SysUserTransfer.class);
        List<SysUserBO> sysUserBOS = sysUserTransfer.transfers(sysUserDOS);

        // 3.批量打印实体内容
        for (int i = 0; i < 10; i++) {
            System.out.println("sysUserDO = " + sysUserDOS.get(i));
            System.out.println("sysUserBO = " + sysUserBOS.get(i));
            System.out.println("-----------------------------------------------------------------------------");
        }
    }
}
  • 单一实体转换结果
    实体属性映射框架mapstruct_第1张图片
  • 批量实体转换结果
    实体属性映射框架mapstruct_第2张图片

4. 嵌套映射

系统用户实体中包含系统角色属性的嵌套实体转换

4.1 持久层实体类

  • 持久层系统角色实体类
@Getter
@Setter
public class SysRoleDO implements Serializable {

    /**
     * 角色编号
     */
    private Long roleId;

    /**
     * 角色描述
     */
    private String roleDesc;

    @Override
    public String toString() {
        return JSON.toJSONString(this);
    }
}
  • 持久层系统用户实体类
@Getter
@Setter
public class SysUserDO implements Serializable {

    /**
     * 用户编号
     */
    private Long userId;

    /**
     * 用户姓名
     */
    private String realName;

    /**
     * 用户角色
     */
    private List<SysRoleDO> roles;

    @Override
    public String toString() {
        return JSON.toJSONString(this);
    }
}

4.2 业务层实体类

  • 业务层系统角色实体类
@Getter
@Setter
public class SysRoleBO {

    /**
     * 角色编号
     */
    private Long roleId;

    /**
     * 角色描述
     */
    private String roleDesc;

    @Override
    public String toString() {
        return JSON.toJSONString(this);
    }
}
  • 业务层系统用户实体类
@Getter
@Setter
public class SysUserBO {

    /**
     * 用户编号
     */
    private Long userId;

    /**
     * 用户姓名
     */
    private String realName;

    /**
     * 用户角色
     */
    private List<SysRoleBO> roles;

    @Override
    public String toString() {
        return JSON.toJSONString(this);
    }
}

4.3 转换层接口

  • 系统角色实体转换接口
@Mapper
public interface SysRoleTransfer {

    /**
     * 实体转换
     *
     * @param role 持久层-系统角色实体
     * @return 业务层-系统角色实体
     */
    @Mappings({
            @Mapping(source = "roleId", target = "roleId"),
            @Mapping(source = "roleDesc", target = "roleDesc")
    })
    SysRoleBO transfer(SysRoleDO role);

    /**
     * 实体列表转换
     *
     * @param roles 持久层-系统角色实体列表
     * @return 业务层-系统角色实体列表
     */
    @Mappings({
            @Mapping(source = "roleId", target = "roleId"),
            @Mapping(source = "roleDesc", target = "roleDesc")
    })
    List<SysRoleBO> transfers(List<SysRoleDO> roles);
}
  • 系统用户实体转换接口
@Mapper
public interface SysUserTransfer {

    /**
     * 实体转换
     *
     * @param user 持久层-系统用户实体
     * @return 业务层-系统用户实体
     */
    @Mappings({
        @Mapping(source = "userId", target = "userId"),
        @Mapping(source = "realName", target = "realName"),
        @Mapping(source = "roles", target = "roles")
    })
    SysUserBO transfer(SysUserDO user);

    /**
     * 实体列表转换
     *
     * @param users 持久层-系统用户实体列表
     * @return 业务层-系统用户实体列表
     */
    @Mappings({
        @Mapping(source = "userId", target = "userId"),
        @Mapping(source = "realName", target = "realName"),
        @Mapping(source = "roles", target = "roles")
    })
    List<SysUserBO> transfers(List<SysUserDO> users);
}

4.4 接口测试类

public class SysUserTransferTest {

    @Test
    public void transfer() {
        SysUserDO sysUserDO = new SysUserDO();
        sysUserDO.setUserId(10001L);
        sysUserDO.setRealName("亡灵天灾");

        SysRoleDO role1 = new SysRoleDO();
        role1.setRoleId(10001L);
        role1.setRoleDesc("超级管理员");

        SysRoleDO role2 = new SysRoleDO();
        role2.setRoleId(10002L);
        role2.setRoleDesc("系统管理员");

        sysUserDO.setRoles(new ArrayList() {{
            add(role1);
            add(role2);
        }});

        SysUserTransfer sysUserTransfer = Mappers.getMapper(SysUserTransfer.class);
        SysUserBO sysUserBO = sysUserTransfer.transfer(sysUserDO);

        System.out.println("sysUserDO = " + sysUserDO);
        System.out.println("sysUserBO = " + sysUserBO);
    }
}

在这里插入图片描述

5. 合并映射

将多个实例映射成一个实例

5.1 转换层接口

@Mapper
public interface SysUserTransfer {

    /**
     * 实体转换
     *
     * @param user 持久层-系统用户实体
     * @param roles 持久层-系统角色实体列表
     * @return 业务层-系统用户实体
     */
    @Mappings({
            @Mapping(source = "user.userId", target = "userId"),
            @Mapping(source = "user.realName", target = "realName"),
            @Mapping(source = "roles", target = "roles")
    })
    SysUserBO transfer(SysUserDO user, List<SysRoleDO> roles);
}

5.2 接口测试类

public class SysUserTransferTest {

    @Test
    public void transfer() {
        SysUserDO sysUserDO = new SysUserDO();
        sysUserDO.setUserId(10001L);
        sysUserDO.setRealName("亡灵天灾");

        SysRoleDO role1 = new SysRoleDO();
        role1.setRoleId(10001L);
        role1.setRoleDesc("超级管理员");

        SysRoleDO role2 = new SysRoleDO();
        role2.setRoleId(10002L);
        role2.setRoleDesc("系统管理员");

        List<SysRoleDO> roles = new ArrayList() {{
            add(role1);
            add(role2);
        }};

        SysUserTransfer sysUserTransfer = Mappers.getMapper(SysUserTransfer.class);
        SysUserBO sysUserBO = sysUserTransfer.transfer(sysUserDO, roles);

        System.out.println("sysUserDO = " + sysUserDO);
        System.out.println("sysUserBO = " + sysUserBO);
    }
}

在这里插入图片描述

6. 特殊映射

(1)常量

(2)默认值

(3)表达式

(4)自定义映射

6.1 转换层接口

@Mapper(imports = {UUID.class})
public interface SysUserTransfer {

    /**
     * 实体转换
     *
     * @param user 持久层-系统用户实体
     * @return 业务层-系统用户实体
     */
    @Mappings({
        @Mapping(target = "userId", constant = "1001L"),
        @Mapping(source = "age", target = "age", defaultValue = "25"),
        @Mapping(target = "realName", expression = "java(UUID.randomUUID().toString())"),
        @Mapping(source = "hight", target = "hight", qualifiedByName = "hightHandle")
    })
    SysUserBO transfer(SysUserDO user);

    /**
     * 用户身高特殊处理
     * 
     * @param sourceHight 原始身高
     * @return 结果身高
     */
    @Named(value = "hightHandle")
    default Double hightHandle(Double sourceHight) {
        return Objects.nonNull(sourceHight) ? sourceHight + 10 : sourceHight;
    }
}

6.2 接口测试类

public class SysUserTransferTest {

    @Test
    public void transfer() {
        SysUserDO sysUserDO = new SysUserDO();
        sysUserDO.setUserId(10002L);
        sysUserDO.setRealName("亡灵天灾");
        sysUserDO.setHight(171.50);

        SysUserTransfer sysUserTransfer = Mappers.getMapper(SysUserTransfer.class);
        SysUserBO sysUserBO = sysUserTransfer.transfer(sysUserDO);

        System.out.println("sysUserDO = " + sysUserDO);
        System.out.println("sysUserBO = " + sysUserBO);
    }
}

实体属性映射框架mapstruct_第3张图片

7. 切面处理

(1)映射前置处理

(2)映射后置处理

7.1 转换层接口

@Mapper
public interface SysUserTransfer {

    /**
     * 实体转换
     *
     * @param user 持久层-系统用户实体
     * @return 业务层-系统用户实体
     */
    @Mappings({
        @Mapping(source = "userId", target = "userId"),
        @Mapping(source = "realName", target = "realName"),
        @Mapping(source = "age", target = "age"),
        @Mapping(source = "hight", target = "hight")
    })
    SysUserBO transfer(SysUserDO user);
    
    /**
     * 前置处理
     *
     * @param sourceUser 原始系统用户
     */
    @BeforeMapping
    default void beforeMapping(SysUserDO sourceUser) {
        System.out.println("sourceUser = " + sourceUser);
    }

    /**
     * 后置处理
     * @param targetUser 目标系统用户
     */
    @AfterMapping
    default void afterMapping(@MappingTarget SysUserBO targetUser) {
        System.out.println("targetUser = " + targetUser);
    }
}

7.2 接口测试类

public class SysUserTransferTest {

    @Test
    public void transfer() {
        SysUserDO sysUserDO = new SysUserDO();
        sysUserDO.setUserId(10001L);
        sysUserDO.setRealName("亡灵天灾");
        sysUserDO.setAge(25);
        sysUserDO.setHight(171.50);

        SysUserTransfer sysUserTransfer = Mappers.getMapper(SysUserTransfer.class);
        SysUserBO sysUserBO = sysUserTransfer.transfer(sysUserDO);

        System.out.println("sysUserDO = " + sysUserDO);
        System.out.println("sysUserBO = " + sysUserBO);
    }
}

实体属性映射框架mapstruct_第4张图片

你可能感兴趣的:(java)