MapStruct解决嵌套对象的问题

这几天项目用了一下MapStruct,真是太好用了,相见恨晚啊!真乃开发神器!码农福音!在引强烈推荐一下!
MapStruct可以替代传统的getter和setter方法的转换,并且效率相当,同时省去了手写转换方法的过程,极大提高了开发效率!(省的时间可以。。。嗯。。。你们懂的)

如果是两个简单对象(没有属性为对象的类)可以直接转换,属性名不相同的,可以用@Mappings转换,具体可以参考下面的例子。

废话少说,上代码

1、引入依赖:

  <properties>
<!-- 依赖版本 这里注意如果版本与下面不一致的,有可能有兼容性问题,在此提醒一下-->
    <org.mapstruct.version>1.5.0.RC1</org.mapstruct.version>
    <lombok-mapstruct-binding.version>0.2.0</lombok-mapstruct-binding.version>
  </properties>

<dependency>
      <groupId>org.mapstruct</groupId>
      <artifactId>mapstruct</artifactId>
      <version>${org.mapstruct.version}</version>
</dependency>

<build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.1</version>
        <configuration>
          <source>${java.version}</source>
          <target>${java.version}</target>
          <annotationProcessorPaths>
            <path>
              <groupId>org.mapstruct</groupId>
              <artifactId>mapstruct-processor</artifactId>
              <version>${org.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>
              <!-- 如果是0.1.0 有可能出现生成了maptruct的实现类,但该类只创建了对象,没有进行赋值的情况 -->
              <version>${lombok-mapstruct-binding.version}</version>
            </path>
          </annotationProcessorPaths>
        </configuration>
      </plugin>
    </plugins>
  </build>

 2、测试目标类(需要转换的结果对象)


import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author zhuo yan
 * @created 2022-06-02 15:04:44
 **/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Target {

  private String id;
  private String username;
  private String cname;
  private List<SubBeanInTarget> menus;

  @Data
  @AllArgsConstructor
  @NoArgsConstructor
  public static class SubBeanInTarget {

    private int id;
    private String title;
    private String icon;
    private List<ChildrenTarget> children;


    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static class ChildrenTarget {

      private int id;
      private String title;
      private String path;
    }
  }
}

3、数据来源对象


import java.io.Serializable;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

/**
 * @author zhuo yan
 * @created 2022-06-02 15:06:38
 **/

@Data
@EqualsAndHashCode(callSuper = false)
public class Resource implements Serializable {
  private static final long serialVersionUID = 1L;
  private Long permId;
  private String permName;
  private String permPath;
  private List<SubBeanInResource> menuList;

  @Data
  @AllArgsConstructor
  @NoArgsConstructor
  public static class SubBeanInResource {

    private int subBeanId;
    private String titleName;
    private String iconName;
    private List<ChildrenResource> childrenList;

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static class ChildrenResource {

      private int childId;
      private String childName;
      private String pathName;
    }
  }
}

3、转换工具类


import com.znlh.gyl.warehouse.web.convertor.test.Resource.SubBeanInResource;
import com.znlh.gyl.warehouse.web.convertor.test.Resource.SubBeanInResource.ChildrenResource;
import com.znlh.gyl.warehouse.web.convertor.test.Target.SubBeanInTarget;
import com.znlh.gyl.warehouse.web.convertor.test.Target.SubBeanInTarget.ChildrenTarget;
import java.util.List;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;

/**
 * @author zhuo yan
 * @created 2022-06-02 15:08:31
 **/
@Mapper(componentModel = "spring")
public interface MyConverter {

  @Mappings({
      @Mapping(source = "permId", target = "id"),
      @Mapping(source = "menuList", target = "menus")
  })
  Target convert(Resource perm);

  // 下面的几个方法可以辅助完成上面的那个 Target 转换而写的,在convert方法调用时,会自动调用对象中所嵌套的子对象的转换方法
  List<SubBeanInTarget> convertBeanList(List<SubBeanInResource> userP);

  @Mappings({
      @Mapping(source = "subBeanId", target = "id"),
      @Mapping(source = "titleName", target = "title"),
      @Mapping(source = "iconName", target = "icon"),
      @Mapping(source = "childrenList", target = "children")
  })
  SubBeanInTarget convertSubBean(SubBeanInResource userPerm);

  List<ChildrenTarget> convertChildrenList(List<ChildrenResource> perms);

  @Mappings({
      @Mapping(source = "childId", target = "id"),
      @Mapping(source = "childName", target = "title"),
      @Mapping(source = "pathName", target = "path")
  })
  ChildrenTarget convertChildren(ChildrenResource perm);

}

 4、查看MapStruct自动帮我们生成的类:


import java.util.ArrayList;
import java.util.List;
import javax.annotation.processing.Generated;
import org.springframework.stereotype.Component;

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2022-06-02T16:45:57+0800",
    comments = "version: 1.5.0.RC1, compiler: javac, environment: Java 11.0.15.1 (Oracle Corporation)"
)
@Component
public class MyConverterImpl implements MyConverter {

    @Override
    public Target convert(Resource perm) {
        if ( perm == null ) {
            return null;
        }

        Target target = new Target();

        if ( perm.getPermId() != null ) {
            target.setId( String.valueOf( perm.getPermId() ) );
        }
        target.setMenus( convertBeanList( perm.getMenuList() ) );

        return target;
    }

    @Override
    public List<Target.SubBeanInTarget> convertBeanList(List<Resource.SubBeanInResource> userP) {
        if ( userP == null ) {
            return null;
        }

        List<Target.SubBeanInTarget> list = new ArrayList<Target.SubBeanInTarget>( userP.size() );
        for ( Resource.SubBeanInResource subBeanInResource : userP ) {
            list.add( convertSubBean( subBeanInResource ) );
        }

        return list;
    }

    @Override
    public Target.SubBeanInTarget convertSubBean(Resource.SubBeanInResource userPerm) {
        if ( userPerm == null ) {
            return null;
        }

        Target.SubBeanInTarget subBeanInTarget = new Target.SubBeanInTarget();

        subBeanInTarget.setId( userPerm.getSubBeanId() );
        subBeanInTarget.setTitle( userPerm.getTitleName() );
        subBeanInTarget.setIcon( userPerm.getIconName() );
        subBeanInTarget.setChildren( convertChildrenList( userPerm.getChildrenList() ) );

        return subBeanInTarget;
    }

    @Override
    public List<Target.SubBeanInTarget.ChildrenTarget> convertChildrenList(List<Resource.SubBeanInResource.ChildrenResource> perms) {
        if ( perms == null ) {
            return null;
        }

        List<Target.SubBeanInTarget.ChildrenTarget> list = new ArrayList<Target.SubBeanInTarget.ChildrenTarget>( perms.size() );
        for ( Resource.SubBeanInResource.ChildrenResource childrenResource : perms ) {
            list.add( convertChildren( childrenResource ) );
        }

        return list;
    }

    @Override
    public Target.SubBeanInTarget.ChildrenTarget convertChildren(Resource.SubBeanInResource.ChildrenResource perm) {
        if ( perm == null ) {
            return null;
        }

        Target.SubBeanInTarget.ChildrenTarget childrenTarget = new Target.SubBeanInTarget.ChildrenTarget();

        childrenTarget.setId( perm.getChildId() );
        childrenTarget.setTitle( perm.getChildName() );
        childrenTarget.setPath( perm.getPathName() );

        return childrenTarget;
    }
}

 大功告成!实际上我们的开发代码只有一个MyConverter!嗯,真香!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值