这几天项目用了一下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!嗯,真香!