MapStruct 对象映射

MapStruct 对象映射

MapStruct 是一个非常实用的 Java 对象映射工具,它可以帮助你轻松地完成不同类型之间的转换。相对于手动进行对象映射,MapStruct 可以减少很多模板代码的编写,提高开发效率,同时也可以减少因手动映射而产生的错误。

MapStruct 在处理简单对象转换时效果非常好,而且易于学习和使用。它提供了很多自定义配置和扩展点,可以满足各种不同场景下的需求。

总的来说,MapStruct 是一款非常实用的 Java 对象映射工具,特别适合处理简单对象转换的场景。如果项目需要进行大量对象映射,那么可以考虑使用 MapStruct 来提高开发效率和减少错误。

官方手册:MapStruct 1.5.3.Final Reference Guide

注:对于mapstruct这个映射框架,并没有非常深入的学习,选择用的时候再去详细查的方式,所以你现在看到的文章内容并不是mapstruct的全部功能,不能满足个人需求时,可以再查阅下其它文章;当然后续我也会不断完善这篇文章,将实际项目中涉及到转换的方式记录下来,当作笔记,以便后续查询。

样例

第一步,导入依赖:

		<!--        对象映射框架-->
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
        </dependency>

需要注意的是,mapstruct与lombok都是在编译前运行,所以这个插件需要有先后顺序,也就是lombok先执行,否则mapstruct参数使用到了通过lombok的@Data注解的参数,会出现字段不能正常获取的问题,解决办法(设置编译插件):

<plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <!--                    depending on your project-->
                    <source>${jdk.version}</source>
                    <!--                    depending on your project-->
                    <target>${jdk.version}</target>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.mapstruct</groupId>
                            <artifactId>mapstruct-processor</artifactId>
                            <version>${mapstruct.plugin.version}</version>
                        </path>
                        <path>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                            <version>${lombok.plugin.version}</version>
                        </path>
                        <path>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok-mapstruct-binding</artifactId>
                            <version>0.2.0</version>
                        </path>
                        <!--                         other annotation processors -->
                    </annotationProcessorPaths>
                </configuration>
            </plugin>

第二步,编写一个example(同类型、名字,不需要配置):

public class Example {
    
    

    private String name;

    private Integer age;
}

public class ExampleVo {
    
    
    private String name;
    private Integer age;
}


@Mapper
public interface ExampleConverter {
    
    

    ExampleConverter INSTANCE = Mappers.getMapper(ExampleConverter.class);

    ExampleVo toVo(Example example);

    List<ExampleVo> toVo(List<Example> examples);
}

总结:

扫描二维码关注公众号,回复: 15339387 查看本文章
  • 导入Maven依赖。
  • 创建接口或者抽象类Mapper对象,并使用@Mapper注解。
  • 通过Mappers工厂,创建INSTANCE实例。
  • 编写bean对象转换规则,可使用@Mappings注解(类型、名称相同时,可省略@Mappings注解)或者default默认实现。
  • 使用静态对象进行转换,例如ExampleConverter.INSTANCE.toVo();

案例

在java中bean的种类很多,如vo、pojo、dto等。出现需要bean类型转换的时候就可以使用mapstruct十分方便。

状态(数字转字符串)

例如:状态(0:禁用,1:启用)、性别(0:未知,1:男性,2:女性)Integer转String。

Bean对象:

// 省略不需要的代码
public class User {
    
    
    /**
     * 用户名
     */
    private String username;
    /**
     * 昵称
     */
    private String nickname;
    /**
     * 性别(0:未知,1:男性,2:女性)
     */
    private Integer gender;
    /**
     * 状态(0:禁用,1:启用)
     */
    private Integer status;
    /**
     * 创建时间
     */
    private LocalDateTime createTime;
	/**
     * 省略其它不用的字段...
     */
}


@ApiModel("用户查询信息对象")
public class UserQueryVo {
    
    
    @ApiModelProperty("账号")
    private String username;

    @ApiModelProperty("昵称")
    private String nickname;

    @ApiModelProperty("状态(0:禁用,1:启用)")
    private String status;

    @ApiModelProperty("性别(0:未知,1:男性,2:女性)")
    private String gender;

    @ApiModelProperty("创建时间")
    private String createTime;
}

Mapper对象,这里涉及到不同Integer类型,代表不同的含义,处理方式使用@Named自定义转换规则,并在@Mapping注解qualifiedByName参数选择自定义转换规则:

@Mapper
public interface UserConverter {
    
    

    UserConverter INSTANCE = Mappers.getMapper(UserConverter.class);

    @Named("status")
    default String status(Integer status) {
    
    
        String result;
        switch (status) {
    
    
            case 0:
                result = "禁用";
                break;
            case 1:
                result = "启用";
                break;
            default:
                result = "-";
        }
        return result;
    }

    @Named("gender")
    default String gender(Integer gender) {
    
    
        String result;
        switch (gender) {
    
    
            case 0:
                result = "未知";
                break;
            case 1:
                result = "男性";
                break;
            case 2:
                result = "女性";
                break;
            default:
                result = "-";
        }
        return result;
    }

    @Mappings({
    
    
            @Mapping(source = "username", target = "username", defaultValue = "-"),
            @Mapping(source = "nickname", target = "nickname", defaultValue = "-"),
            @Mapping(source = "status", target = "status", qualifiedByName = "status", defaultValue = "-"),
            @Mapping(source = "gender", target = "gender", qualifiedByName = "gender"),
            @Mapping(source = "createTime", target = "createTime", defaultValue = "-", dateFormat = "yyyy-MM-dd HH:mm:ss"),
    })
    UserQueryVo toVo(User data);

    List<UserQueryVo> toVo(List<User> data);

    @Mappings({
    
    
            @Mapping(source = "username", target = "username"),
            @Mapping(source = "phone", target = "mobile"),
    })
    User toPojo(UserQueryParam param);
}

实际代码:

    @Override
    public List<UserQueryVo> queryUsers(UserQueryParam param) {
    
    
        // 转换
        User user = UserConverter.INSTANCE.toPojo(param);
        Page page = PageConverter.INSTANCE.toPojo(param);

        // 查询
        List<User> users = userMapper.selectUsers(user, page);

        // 转vo
        return UserConverter.INSTANCE.toVo(users);
    }

页(计算偏移)

Bean对象:

@Data
@ApiModel("分页参数")
public class PageVo {
    
    

    /**
     * 页大小
     */
    @Digits(fraction = 0, integer = 3, message = "长度不能超过3位,请输入合法参数!")
    @NotNull(message = "参数不能为空!")
    private Integer pageSize;

    /**
     * 页码
     */
    @Digits(fraction = 0, integer = 3, message = "长度不能超过3位,请输入合法参数!")
    @NotNull(message = "参数不能为空!")
    private Integer pageNo;

}

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

    /**
     * 页大小
     */
    private Integer pageSize;

    /**
     * 页码
     */
    private Integer pageNo;

    /**
     * 偏移 = (pageNo - 1) * pageSize
     */
    private Integer offset;
}

Mapper对象,使用expression来计算偏移:

@Mapper
public interface PageConverter {
    
    

    PageConverter INSTANCE = Mappers.getMapper(PageConverter.class);

    @Mappings({
    
    
            @Mapping(source = "vo.pageSize", target = "pageSize"),
            @Mapping(source = "vo.pageNo", target = "pageNo"),
            @Mapping(target = "offset", expression = "java((vo.getPageNo() - 1) * vo.getPageSize())"),
    })
    Page toPojo(PageVo vo);

}

猜你喜欢

转载自blog.csdn.net/qq_19152901/article/details/129477450