栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

优雅的转换拷贝对象—MapStruct

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

优雅的转换拷贝对象—MapStruct

MapStruct是什么

项目经常有这样的场景,我要把对象a的name转换到对象b的name去,我们经常是使用BeanUtils.copyProperties();方法去实现的,但是这样做很大的弊端,使用反射的方式的效率慢对性能的消耗比较大, 有安全问题等等,更有的同事使用get,set方法,字段一多,这就太麻烦了。
那怎么办呢?优雅转换大师MapStruct出场MapStruct就是一个属性映射工具,与手动编写映射代码相比,MapStruct通过生成繁琐且易于出错的代码来节省时间。约定优于配置的方式,MapStruct使用合理的默认值,但在配置或实现特殊行为时不加理会。 MapStruct优点

和动态映射框架相比,MapStruct具有以下优点:

通过使用普通方法调用而不是反射来快速执行编译时类型安全性构建是清除错误报告可自定义属性映射 MapStruct使用

这里示范一下基于maven的使用方式


  1.4.1.Final


	
			org.mapstruct
			mapstruct-processor
			${org.mapstruct.version}
		
		
			org.mapstruct
			mapstruct-jdk8
			${org.mapstruct.version}
		
		
			org.mapstruct
			mapstruct
			${org.mapstruct.version}
		



		
			
				org.apache.maven.plugins
				maven-compiler-plugin
				3.8.1
				
					1.8
					1.8
					
						
							org.mapstruct
							mapstruct-processor
							${org.mapstruct.version}
						
						
							org.projectlombok
							lombok
							1.18.22
						
						
							org.projectlombok
							lombok-mapstruct-binding
							0.2.0
						
					
				
			
		
	
MapStruct代码生成器处理器选项配置
- mapstruct.suppressGeneratorTimesstamp

如果设置为true,将禁止在生成的映射器类中创建时间戳
默认为false

- mapstruct.suppressGeneratorVersionInfoComment

如果设置为true,将禁止在生成的映射器类中创建属性
默认为false

- mapstruct.defaultComponentModel

基于生成映射器的组件模型的名称
支持:default,cdi,spring,jsr330
默认为default,使用spring可以使用@Autowired方式注入

- mapstruct.unmappedTargetPolicy

在未使用source值填充映射方法的target的属性的情况下要应用的默认报告策略。
支持:ERROR(映射代码生成失败),WARN(构建时引起警告),IGNORE(将被忽略)
默认为WARN

具体配置方式

    org.apache.maven.plugins
    maven-compiler-plugin
    3.8.1
    
        1.8
        1.8
        
            
                org.mapstruct
                mapstruct-processor
                ${org.mapstruct.version}
            
        
        
            
                -Amapstruct.suppressGeneratorTimestamp=true
            
            
                -Amapstruct.suppressGeneratorVersionInfoComment=true
            
        
    

创建用户类
@Data
@ApiModel(value = "用户")
public class SysUser implements Serializable {

	private static final long serialVersionUID = 1L;

	
	@TableId(value = "user_id", type = IdType.INPUT)
	@ApiModelProperty(value = "主键id")
	private Long userId;

	
	@ApiModelProperty(value = "用户名")
	private String username;
}
创建用户VO
@Data
@ApiModel(value = "前端用户展示对象")
public class UserVO implements Serializable {

	private static final long serialVersionUID = 1L;

	
	@ApiModelProperty(value = "主键")
	private Long userId;

	
	@ApiModelProperty(value = "用户名")
	private String username;
}
创建一个转换接口
@Mapper
public interface SysUserMapperConvert {

    SysUserMapperConvert INSTANCE = Mappers.getMapper(SysUserMapperConvert.class);
	
    UserVO toConvertUserVo(SysUser user);
    
 }

说明:
该@Mapper注解将使用MapStruct代码生成器创建对应的映射类

在生成的方法实现中,source类型的所有可读属性都将复制到target类型的相应属性中

当一个属性于其target实体对应的名称相同时,它将被隐式映射
生成的代码如下:

调用user转userVO方法就会自动转换
public UserVO findUserByRealName(String realName) {
        SysUser sysUsers = this.getOne(Wrappers.lambdaQuery().eq(SysUser::getRealName, realName));
        return SysUserMapperConvert.INSTANCE.toConvertUserVo(sysUsers);
    }
通过接口方法 看自动生成的代码如下

(编译自动生成的)

 @Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2021-12-26T17:50:36+0800",
    comments = "version: 1.4.1.Final, compiler: javac, environment: Java 1.8.0_111 (Oracle Corporation)"
)
public class SysUserMapperConvertImpl implements SysUserMapperConvert {
    @Override
    public UserVO toConvertUserVo(SysUser user) {
        if ( user == null ) {
            return null;
        }
        UserVO userVO = new UserVO();
        userVO.setUserId( user.getUserId() );
        userVO.setUsername( user.getUsername() );
        return userVO;
    }
}

MapStruct的原理是生成和自己写的代码一样的代码,这意味着这些值是通过简单的getter/setter调用而不是反射或类似的方法从source类复制到target类的。使得MapStruct的性能会比动态框架更加优秀。 自定义属性映射

当属性在target实体中具有不同的名称时,可以通过@Mapping注释指定其名称。

	
	 @Mapping(target = "username",source = "id")    
    UserVO toConvertUserVo(SysUser user);
多个source参数的映射

mapstruct支持多个source对象聚合成一个target的场景
如:需要将person的中description映射到UserVO中的description
将SysUser的name映射到UserVO中的username

@Mapping(source = "person.description", target = "description")
    @Mapping(source = "user.username", target = "name")
    UserVO toConvertUserVo(Person person, SysUser user);

常用的一些方法方式基本上就是上面这些了,如果还需要更多的用法请到官网了解学习!MapStruct是否足够优雅呢?有任何问题欢迎评论区留言讨论!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/748942.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号