首页 > 编程语言 >Java对象拷贝MapStruct

Java对象拷贝MapStruct

时间:2023-06-17 21:00:51浏览次数:65  
标签:Java ap MapStruct DefaultVersionInformation mapstruct org java 拷贝 processor


介绍

编译期即可生成对象复制代码。简单理解,功能定位org.springframework.beans.BeanUtils
官网GitHub-MapStruct

入门

maven项目引入依赖:

  1. mapstruct:包含必要注解,如@Mapping
  2. mapstruct-processor:注解处理器,根据注解自动生成mapper实现
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct</artifactId>
</dependency>
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-processor</artifactId>
</dependency>

实战:

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;

// 如果增加componentModel 增生成的实现类有注解@Component
@Mapper(componentModel = "spring")
public interface AccountConvert {

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

    @Mappings({
            @Mapping(target = "username", source = "userName")
            @Mapping(source = "userTypeEnum", target = "type")
			@Mapping(target = "createTime", expression = "java(com.java.mmzsblog.util.DateTransform.strToDate(source.getCreateTime()))"),

    })
    Account dto2Entity(AccountDTO dto);

	@Data
	private static class Account {
		private string username;
	}
	
	@Data   
  	private static class AccountDTO {
		private string userName;
	}

	@Getter
	@AllArgsConstructor
	public enum UserTypeEnum {
	    JAVA("000", "Java开发工程师"),
	    DB("001", "数据库管理员");	    
	    private String value;
	    private String title;
	}

生成class文件:

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2023-06-10T12:52:02+0800",
    comments = "version: 1.5.5.Final, compiler: javac, environment: Java 11.0.18 (Azul Systems, Inc.)"
)
public class AccountConvertImpl implements AccountConvert {
	@Override
    public Account dto2Entity(AccountDTO dto) {
        if (dto == null) {
            return null;
        }
        Account account = new Account();
        account.setUsername(dto.getUserName());
        return account;
    }
}

Spring Bean

使用@Mapper注解时,如果备注componentModel = "spring",则可以把AccountConvert当做一个Spring Bean来使用:

@Resource
private DrugConverter drugConverter;

Java对象拷贝MapStruct_java

原理

当字段类型不一致时,MapStruct能够自动实现类型转换的类型:

  1. 基本类型及其对应的包装类型
  2. 基本类型的包装类型和String类型之间

除此之外的类型转换,可以通过定义表达式来进行指定转换。

注解

  • @Mapper,用于接口类,可以理解为定义一个静态类或Spring Bean类
  • @Mapping,指定source和target实体类的映射关系
  • @Mappings,多个@Mapping的合集
  • @MapMapping:
  • @BeanMapping:
  • @BeforeMapping & @AfterMapping:类似于Junit的@BeforeTest和@AfterTest,在@Mapping之前和之后做一些处理
  • @InheritConfiguration:
  • @InheritInverseConfiguration:已经存在DTO转PO的接口方法定义时,需要一个PO转DTO的接口时,可使用此注解,省去source、target、dateFormat等信息的配置维护

数据类型映射

MapStruct支持source和target属性之间的数据类型转换,还提供类型自动转换,适用于:

  • 基本类型及其对应的包装类之间
  • 任意基本类型与任意包装类之间,如 byte 和 Integer
  • 所有基本类型及包装类与String之间
  • 枚举和String之间
  • Java大数类型(java.math.BigIntegerjava.math.BigDecimal) 和Java基本类型(包括其包装类)与String之间。

日期转换,可使用dateFormat标志指定日期格式;
数字转换,可使用numberFormat指定显示格式

枚举映射

实战

记录使用遇到的问题

Internal error in the mapping processor: java.lang.NullPointerException

IDEA 2022.1.4 (Ultimate Edition)版本,以Debug模式启动应用,失败:

java: Internal error in the mapping processor: java.lang.NullPointerException
at org.mapstruct.ap.internal.processor.DefaultVersionInformation.createManifestUrl(DefaultVersionInformation.java:182)      at org.mapstruct.ap.internal.processor.DefaultVersionInformation.openManifest(DefaultVersionInformation.java:153)      at org.mapstruct.ap.internal.processor.DefaultVersionInformation.getLibraryName(DefaultVersionInformation.java:129)      at org.mapstruct.ap.internal.processor.DefaultVersionInformation.getCompiler(DefaultVersionInformation.java:122)
at org.mapstruct.ap.internal.processor.DefaultVersionInformation.fromProcessingEnvironment(DefaultVersionInformation.java:95)
at org.mapstruct.ap.internal.processor.DefaultModelElementProcessorContext.<init>(DefaultModelElementProcessorContext.java:54)
at org.mapstruct.ap.MappingProcessor.processMapperElements(MappingProcessor.java:264)
at org.mapstruct.ap.MappingProcessor.process(MappingProcessor.java:166)
at org.jetbrains.jps.javac.APIWrappers$ProcessorWrapper.process(APIWrappers.java:157)

参考,解决方法:升级MapStruct pom依赖,1.4.0.Final -> 当前最新版1.5.5.Final

No target bean properties found: can’t map Collection element, Consider to declare/implement a mapping method

应用以Debug模式启动报错:

java: No target bean properties found: can't map Collection element "DrugEsEntity drugEsEntity" to "DrugListVo drugListVo". Consider to declare/implement a mapping method: "DrugListVo map(DrugEsEntity value)".

现有接口定义:

@Mapper
public interface DrugConverter {
    DrugConverter INSTANCE = Mappers.getMapper(DrugConverter.class);
    
    List<DrugListVo> esToVos(List<DrugEsEntity> entities);
}

解决方法,增加接口:

DrugListVo esToVo(DrugEsEntity entity);

这在生成的DrugConverterImpl代码中可见一斑:

Java对象拷贝MapStruct_包装类_02

参考

MapStruct 1.5发布支持Map转为Bean


标签:Java,ap,MapStruct,DefaultVersionInformation,mapstruct,org,java,拷贝,processor
From: https://blog.51cto.com/u_15851118/6506230

相关文章

  • Java基本概念
    1.Java发展历史由高斯林创建1995年由甲骨文公司收购并发出第一版本,目前使用最多是Java8及Java11原因是这两个版本都是长期支持维护的,企业用的也比较多。2.Java的一些特点跨平台性:主要是因为每个平台都装有JVMJava是一门解释语言,即由解释器解释完后,再通过JVM运行......
  • Java彩虹渐变算法
    彩虹渐变算法前言​ 最近有一个需求是需要一直去改变字体的颜色,然后我就想到了使用彩虹颜色作为字体颜色,使颜色按照彩虹颜色的顺序进行变化。​ 然后查了一下彩虹的颜色可以分为6种(对,不是七种),用RGB来表示分别是#FF00FF,#FFFF00,#00FF00,#00FFFF,#0000FF,#FF00FF,因此我们只需要......
  • java中 如何在文本中筛选出汉字
    在Java中,使用正则表达式来筛选出文本中的汉字。下面是一种方法:importjava.util.regex.Matcher;importjava.util.regex.Pattern;publicclassMain{publicstaticvoidmain(String[]args){Stringtext="Hello你好!Thisisatest文本。";//使......
  • java中 如何在文本中筛选出汉字
    在Java中,使用正则表达式来筛选出文本中的汉字。下面是一种方法:importjava.util.regex.Matcher;importjava.util.regex.Pattern;publicclassMain{publicstaticvoidmain(String[]args){Stringtext="Hello你好!Thisisatest文本。";//使......
  • java使double保留两位小数的多方法 java保留两位小数
    代码如下:mportjava.text.DecimalFormat;  DecimalFormat   df  =newDecimalFormat("######0.00");  doubled1=3.23456 doubled2=0.0;doubled3=2.0;df.format(d1);df.format(d2);df.format(d3);3个结果分别为:复制代码代码如下:3.230.002.00java保留两位小......
  • Java官方笔记11包
    PackagesDefinition:Apackageisagroupingofrelatedtypesprovidingaccessprotectionandnamespacemanagement.Notethattypesreferstoclasses,interfaces,enumerations,andannotationtypes.Enumerationsandannotationtypesarespecialkindsof......
  • java中 如何在文本中筛选出汉字
    在Java中,使用正则表达式来筛选出文本中的汉字。下面是一种方法:importjava.util.regex.Matcher;importjava.util.regex.Pattern;publicclassMain{publicstaticvoidmain(String[]args){Stringtext="Hello你好!Thisisatest文本。";/......
  • java中 如何在文本中筛选出汉字
    在Java中,使用正则表达式来筛选出文本中的汉字。下面是一种方法:importjava.util.regex.Matcher;importjava.util.regex.Pattern;publicclassMain{publicstaticvoidmain(String[]args){Stringtext="Hello你好!Thisisatest文本。";/......
  • JavaScript之Object.defineProperty()
    1.对象的定义与赋值经常使用的定义与赋值方法obj.prop=value或者obj['prop']=valueletPerson={};Person.name="Jack";Person["gender"]="female";console.log(Person.name);//Jackconsole.log(Person.gender);//femaleconsole.log(Pers......
  • Java官方笔记10注解
    注解注解的作用:Informationforthecompiler—Annotationscanbeusedbythecompilertodetecterrorsorsuppresswarnings.Compile-timeanddeployment-timeprocessing—Softwaretoolscanprocessannotationinformationtogeneratecode,XMLfiles,ands......