MapStruct 基本使用,项目常见DTO映射转换

MapStruct 是一个 Java 注释处理器,用于为 Java Bean 类生成类型安全和高性能的映射器。可以自动编写映射代码,处理常见实体类的属性映射很方便。

官网:MapStruct – Java bean mappings, the easy way!

目录

一、Maven依赖

二、基本转换

1、相同属性名(实体类、List)

2、不同属性名(实体类、List)

3、自定义属性值

4、多参数转换

5、List转换且其一为固定参数的情况


一、Maven依赖

<!-- 与lombok不冲突的版本 -->
<!--      lombok      -->
<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <version>1.18.10</version>
  <optional>true</optional>
</dependency>
<!-- mapstruct -->
<dependency>
  <groupId>org.mapstruct</groupId>
  <artifactId>mapstruct</artifactId>
  <version>1.3.0.Final</version>
</dependency>
<!--  -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork>
                    <addResources>true</addResources>
                </configuration>
            </plugin>
            <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.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                            <version>${lombok.version}</version>
                        </path>
                        <path>
                            <groupId>org.mapstruct</groupId>
                            <artifactId>mapstruct-processor</artifactId>
                            <version>${mapstruct.version}</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
        </plugins>
    </build>

二、基本转换

        演示实体类:

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class RoleDto {

    @ApiModelProperty("id")
    private Integer id;
    /**
     * 角色名
     */
    @ApiModelProperty("角色名")
    private String roleName;
    /**
     * 描述
     */
    @ApiModelProperty("描述")
    private String remark;
}
@NoArgsConstructor
@AllArgsConstructor
@Data
public class Role implements Serializable {

    @ApiModelProperty("id")
    private Integer id;

    @ApiModelProperty("角色名")
    private String roleName;

    @ApiModelProperty("描述")
    private String description;

    @ApiModelProperty("创建时间")
    @JsonDeserialize(using = LocalDateTimeDeserializer.class)
    @JsonSerialize(using = LocalDateTimeSerializer.class)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createtime;

    @ApiModelProperty("更新时间")
    @JsonDeserialize(using = LocalDateTimeDeserializer.class)
    @JsonSerialize(using = LocalDateTimeSerializer.class)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updatetime;

}

1、相同属性名(实体类、List)

        当相互转换的实体类的属性名相同时,可以直接写方法:

//注意注解导包import org.mapstruct.Mapper;

@Mapper
public interface RoleCovert {
    RoleCovert INSTANCE= Mappers.getMapper(RoleCovert.class);
	// 将对象Role中的属性映射到RoleDto中 (Role中没有remark同名属性,不会映射)
    RoleDto toCovertRole(Role role);
	// 如果需要进行list转换,需要在上面方法的基础上添加一个list方法即可,会利用上述方法转换
    List<RoleDto> toCovertRole(List<Role> roles);


}

        生成的实体类:

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2023-04-12T19:26:11+0800",
    comments = "version: 1.3.0.Final, compiler: javac, environment: Java 1.8.0_131 (Oracle Corporation)"
)
public class RoleCovertImpl implements RoleCovert {

    @Override
    public RoleDto toCovertRole(Role role) {
        if ( role == null ) {
            return null;
        }

        RoleDto roleDto = new RoleDto();

        roleDto.setId( role.getId() );
        roleDto.setRoleName( role.getRoleName() );

        return roleDto;
    }

    @Override
    public List<RoleDto> toCovertRole(List<Role> roles) {
        if ( roles == null ) {
            return null;
        }

        List<RoleDto> list = new ArrayList<RoleDto>( roles.size() );
        for ( Role role : roles ) {
            list.add( toCovertRole( role ) );
        }

        return list;
    }
}

2、不同属性名(实体类、List)

        将Role中的description属性映射到RoleDto的remark属性,需要加注解@Mapping:

@Mapping 可以指定某些特殊映射(@Mapping可以直接加在方法上,也可以选择在方法上加@Mappings包裹@Mapping)

@Mapper
public interface RoleCovert {
    RoleCovert INSTANCE= Mappers.getMapper(RoleCovert.class);
    //将Role中的description属性映射到RoleDto的remark属性
	@Mapping(target = "remark",source = "description")
    RoleDto toCovertRole(Role role);

    List<RoleDto> toCovertRole(List<Role> roles);
}

3、自定义属性值

        @Mapping 也可以设置属性默认常量,或expression表达式设置属性值(如获取当前时间、参数进行某些处理等)

// 将目标类的deleted属性值为常量0
@Mapping(target = "deleted", constant = "0")
// 将目标类的createtimed属性值为当前时间
@Mapping(target = "createtime", expression = "java(java.time.LocalDateTime.now())")

4、多参数转换

        在多个参数属性名不重复,且与目标实体类要映射的属性相同时可以直接使用,否则也可以用注解的方式

@Mappings({
      	将role实体的id值映射到目标实体的roleId属性
        @Mapping(target = "roleId", source = "role.id"), 
        @Mapping(target = "permissionId", source = "permission.id")
})
RolePermission toCovert(Role role, Permission permission);

5、List转换且其一为固定参数的情况

        有时实体类会是联系表,其中A关联Id固定,B为List,然后转换为联系实体List<A_B>:

需要将A固定的Id加 @Context注解,然后再在 @Mapping里用expression = "java(A_Id)"设值。

@Mapper
public interface RolePermissionCovert {
    RolePermissionCovert INSTANCE = Mappers.getMapper(RolePermissionCovert.class);
	// 单实体转换,设置某一属性值固定,之后List也在固定值加@Context注解即可
    // 这里的用的Integer,实际上可以用实体类
    @Mapping(target = "roleId",expression = "java(roleId)")
    RolePermission toCovert(Integer permissionId, @Context Integer roleId);

    List<RolePermission> toCovert(List<Integer> permissionIds, @Context Integer roleId);

}

        生成的实体类

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2023-04-12T19:26:11+0800",
    comments = "version: 1.3.0.Final, compiler: javac, environment: Java 1.8.0_131 (Oracle Corporation)"
)
public class RolePermissionCovertImpl implements RolePermissionCovert {

    @Override
    public RolePermission toCovert(Integer permissionId, Integer roleId) {
        if ( permissionId == null ) {
            return null;
        }

        RolePermission rolePermission = new RolePermission();

        rolePermission.setPermissionId( permissionId );

        rolePermission.setRoleId( roleId );

        return rolePermission;
    }

    @Override
    public List<RolePermission> toCovert(List<Integer> permissionIds, Integer roleId) {
        if ( permissionIds == null ) {
            return null;
        }

        List<RolePermission> list = new ArrayList<RolePermission>( permissionIds.size() );
        for ( Integer integer : permissionIds ) {
            list.add( toCovert( integer, roleId ) );
        }

        return list;
    }
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SS上善

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值