对象自动转换神器mapstruct,完美解决DTO-DO的模型映射

第一步: 引入对应的pom文件

            <!--mapStruct依赖-->
            <dependency>
                <groupId>org.mapstruct</groupId>
                <artifactId>mapstruct-jdk8</artifactId>
                <version>1.2.0.CR1</version>

            </dependency>
            <dependency>
                <groupId>org.mapstruct</groupId>
                <artifactId>mapstruct-processor</artifactId>
                <version>1.2.0.CR1</version>   
                <scope>provided</scope>
            </dependency>

第二步::引入项目辅助pom文件

  <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-test</artifactId>
            <version>2.0.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
        </dependency>

       <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.10</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.70</version>
        </dependency>

这里注意lombok版本要在1.16.10以上

第三步:代码实现

基础接口

@MapperConfig
public interface BaseMapping<S, T> {

    /**
     * 映射同名属性
     */
    @Mapping(target = "createTime", dateFormat = "yyyy-MM-dd HH:mm:ss")
    T sourceToTarget(S var1);

    /**
     * 反向,映射同名属性
     */
    @InheritInverseConfiguration(name = "sourceToTarget")
    S targetToSource(T var1);

    /**
     * 映射同名属性,集合形式
     */
    @InheritConfiguration(name = "sourceToTarget")
    List<T> sourceToTarget(List<S> var1);

    /**
     * 反向,映射同名属性,集合形式
     */
    @InheritConfiguration(name = "targetToSource")
    List<S> targetToSource(List<T> var1);

    /**
     * 映射同名属性,集合流形式
     */
    List<T> sourceToTarget(Stream<S> stream);

    /**
     * 反向,映射同名属性,集合流形式
     */
    List<S> targetToSource(Stream<T> stream);

}

转换实现

@Mapper(componentModel = "spring")
public interface UserMapping extends BaseMapping<UserPO,UserDO> {

    @Mapping(target = "gender", source = "sex")
    @Mapping(target = "createTime", dateFormat = "yyyy-MM-dd HH:mm:ss")
    @Override
    UserDO sourceToTarget(UserPO var1);

    @Mapping(target = "sex", source = "gender")
    @Mapping(target = "password", ignore = true)
    @Mapping(target = "createTime", dateFormat = "yyyy-MM-dd HH:mm:ss")
    @Override
    UserPO targetToSource(UserDO var1);

    /**
     * 自定义转换
     * @param config
     * @return
     */
    default List<UserDO.UserConfig> strConfigToListUserConfig(String config) {
        return JSON.parseArray(config, UserDO.UserConfig.class);
    }


    /**
     * 自定义转换
     * @param list
     * @return
     */
    default String listUserConfigToStrConfig(List<UserDO.UserConfig> list) {
        return JSON.toJSONString(list);
    }

}

对象DO如下:

@Data
@Accessors(chain = true)
public class UserDO {
    private Long id;
    private String username;
    private String password;
    private Integer gender;
    private LocalDate birthday;
    private String createTime;
    private List<UserConfig> config;
    private String test; 
    @Data
    public static class UserConfig {
        private String field1;
        private Integer field2;
    }

对象DO如下:

@Data
@Accessors(chain = true)
public class UserPO {
    private Long id;
    private String username;
    private String password; // 密码
    private Integer sex;  // 性别
    private LocalDate birthday; // 生日
    private LocalDateTime createTime; // 创建时间
    private String config; // 其他扩展信息,以JSON格式存储
    private String test; // 测试字段
}

开始测试

@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestNew {


    @Resource
    private UserMapping userMapping;

    @Test
    public void tetDomain2DTO() {
        UserPO userPO = new UserPO()
                .setId(1L)
                .setUsername("dayong")
                .setSex(1)
                .setPassword("1232131")
                .setCreateTime(LocalDateTime.now())
                .setBirthday(LocalDate.of(1992, 11, 11))
                .setConfig("[{\"field1\":\"Test Field1\",\"field2\":500}]");
        UserDO userDO = userMapping.sourceToTarget(user);
        log.info("userPO : {}", userPO );
        log.info("UserVo: {}", userDO);
    }

    @Test
    public void testDTO2Domain() {
        UserDO.UserConfig userConfig = new UserDO.UserConfig();
        userConfig.setField1("Test Field1");
        userConfig.setField2(500);
        UserDO userDO = new UserDO()
                .setId(1L)
                .setUsername("dayong")
                .setGender(2)
                .setCreateTime("2020-01-18 15:32:54")
                .setBirthday(LocalDate.of(1992, 11, 11))
                .setConfig(Collections.singletonList(userConfig));
        UserPO userPO = userMapping.targetToSource(userDO);
        log.info("UserDO: {}", userDO);
        log.info("userPO: {}", userPO);
    }

关于DTO可自行创建这里不做赘述了

这样我们就完成了,自动转换,如果属性字段名称相同那么,在编译器mapStruct会在编译阶段完成映射你可以在你的项目中target目录中查看,使用中注意的对应的和lombok的版本,可以参考官方文档有很多奇妙的使用方式

使用注意点:
当两个对象属性不一致时,比如User对象中某个字段不存在与UserVo当中时,在编译时会有警告提示,可以在@Mapping中配置 ignore = true,当字段较多时,可以直接在@Mapper中设置unmappedTargetPolicy属性或者unmappedSourcePolicy属性为 ReportingPolicy.IGNORE就可以了

5种常见的bean对象转换对比

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值