在Eclipse中使用MapStruct

由于Dozer不再维护,公司内部的项目需要从Dozer转移到MapStruct,自学了一下MapStruct的使用方法。

MapStruct简介

MapStruct与传统的复制 JavaBean 的工具不同(比如Dozer),并不提供JavaBean转换的方法,他只是个代码生成的工具,会自动将JavaBean转换的方法生成到本地,从而在代码中直接调用生成的方法,避免了反射的使用,一定程度上提高了性能

MapStruct是编译时的工具,与Dozer等运行时的工具相比,在程序运行时不会调用MapStruct本身,而是使用MapStruct编译时生成的代码,从而可以进行debug,并且由于是编译时就已经生成的代码,可以在编译时发现错误。

但是与Dozer等相比,MapStruct需要自动生成代码,是编译时的工具,需要在编译时就指定转换前和转换后的Bean的类的类型,不能像Dozer等一样的使用泛型和Object来实现任意类型的Bean转换

在Eclipse中使用MapStruct

介绍在Eclipse中的Maven工程里使用MapStruct
使用其他工具可以参照官网教程 https://mapstruct.org/documentation/installation/

1.添加依赖
在pom.xml中加入以下代码

...
<properties>
    <org.mapstruct.version>1.5.3.Final</org.mapstruct.version>
</properties>
...
<dependencies>
    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct</artifactId>
        <version>${org.mapstruct.version}</version>
    </dependency>
</dependencies>
...
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <source>1.8</source> <!-- depending on your project -->
                <target>1.8</target> <!-- depending on your project -->
                <annotationProcessorPaths>
                    <path>
                        <groupId>org.mapstruct</groupId>
                        <artifactId>mapstruct-processor</artifactId>
                        <version>${org.mapstruct.version}</version>
                    </path>
                    <!-- other annotation processors -->
                </annotationProcessorPaths>
            </configuration>
        </plugin>
    </plugins>
</build>

2.安装自动处理注解的工具(Eclipse - m2e-apt)
如果不安装,将不会自动生成代码,可以通过mvn命令手动编译来生成本地代码,但是这样不会实时修改生成的代码,建议安装m2e-apt

安装方法:打开Eclipse - Help - Eclipse Marketplace
搜索m2e-apt 按下Install
在这里插入图片描述

安装完后在工程的pom.xml的properties继续中加入以下代码

<properties>
...
  <!-- automatically run annotation processors within the incremental compilation -->
  <m2e.apt.activation>jdt_apt</m2e.apt.activation>
...
</properties>

示例

经过上述步骤已经可以在工程内使用MapStruct了

1.引入MapStruct 首先要创建一个MapStruct的接口
创建一个接口,并加上@Mapper注解,这样一个MapStruct接口就做好了

import org.mapstruct.Mapper;

@Mapper
public interface MyMapStruct {

}

查看target/generated-sources/annotations目录下,生成了接口的实现类
在这里插入图片描述

打开可以看到自动生成的代码
在这里插入图片描述
2.接下来定义需要转换的Bean类

public class DTO01 {
	
	private String field01;
	private String field02;
	public String getField01() {
		return field01;
	}
	public void setField01(String field01) {
		this.field01 = field01;
	}
	public String getField02() {
		return field02;
	}
	public void setField02(String field02) {
		this.field02 = field02;
	}

}
public class DTO02 {

	private String field01;
	private String field02;
	public String getField01() {
		return field01;
	}
	public void setField01(String field01) {
		this.field01 = field01;
	}
	public String getField02() {
		return field02;
	}
	public void setField02(String field02) {
		this.field02 = field02;
	}
}

3.在接口中定义转换方法
只需要定义方法的返回类型 名字和参数即可,MapStruct会自动生成实现方法
方法名是任意的,自己起名即可

import org.mapstruct.Mapper;

@Mapper
public interface MyMapStruct {
     DTO01 DTO02_To_DTO01(DTO02 dto02);
}

查看target/generated-sources/annotations目录下的实现类
![在这里插入图片描述](https://img-blog.csdnimg.cn/e03c1964fc4a4d3cbb366b71eab64024.png

MapStruct自动生成了转换方法,实际上也是基于set get方法来实现的,简单易读

4.调用方法
首先实例化对象,然后像普通方法一样通过对象调用即可
实例化方法

		MyMapStruct myMapStruct = Mappers.getMapper(MyMapStruct.class);

如果使用Spring等框架来管理bean,也可以使用Inject注解来实例化

	@Inject
	MyMapStruct myMapStruct;

测试:

import org.mapstruct.factory.Mappers;

public class MapStructTest {
	
	public static void main(String[] args) {
		DTO02 dto02 = new DTO02();
		dto02.setField01("01");
		dto02.setField02("02");
		
		//实例化
		MyMapStruct myMapStruct = Mappers.getMapper(MyMapStruct.class);
		
		DTO01 dto01 = myMapStruct.DTO02_To_DTO01(dto02);
		System.out.println(dto01.getField01());
		System.out.println(dto01.getField02());
		
	}

}

成功将DTO02的值复制给了DTO01

5.自定义转换方法
如果不想使用MapStruct自动生成的方法也可以在接口中自定义

可以使用default 关键字,并自己添加方法体来实现,必须要return

import org.mapstruct.Mapper;

@Mapper
public interface MyMapStruct {
     DTO01 DTO02_To_DTO01(DTO02 dto02);
     
     default DTO01 MyMethod(DTO02 dto02){
    	 DTO01 dto01 = new DTO01();
    	 dto01.setField01(dto02.getField01() + "my1");
    	 dto01.setField02(dto02.getField02() + "my2");
    	 return dto01;
     }
     
}

6.自定义某个字段的转换
如果Bean中的字段需要特殊的转换,也可以自己来实现
例如
将DTO01中的field01 修改为boolean类型
DTO02中的field01 修改为 int类型


public class DTO01 {
	
	private boolean field01;
	private String field02;
	public boolean isField01() {
		return field01;
	}
	public void setField01(boolean field01) {
		this.field01 = field01;
	}
	public String getField02() {
		return field02;
	}
	public void setField02(String field02) {
		this.field02 = field02;
	}


}

public class DTO02 {

	private int field01;
	private String field02;
	public int getField01() {
		return field01;
	}
	public void setField01(int field01) {
		this.field01 = field01;
	}
	public String getField02() {
		return field02;
	}
	public void setField02(String field02) {
		this.field02 = field02;
	}

}

在这里插入图片描述
这时候接口在报错

Can’t map property “int field01” to “boolean field01”. Consider to declare/implement a mapping method: “boolean map(int value)”.
由于int无法转换成boolean ,mapStruct无法自动生成代码,所以需要自己来定义该字段的转换

首先定义自己的转换逻辑方法,并加上@Named注解,定义一个别名
注意:是这个包下的Named org.mapstruct.Named

     @Named("toBoolean")
     default boolean intToBoolean(int value) {
    	 if (value >0) {
    		 return true;
    	 }else {
    		 return false;
    	 }
     }

然后在转换方法上使用@Mapping注解,target = 需要转换的字段名 qualifiedByName = 自定义的转换方法别名(@Named上定义的)

	 @Mapping(target = "field01", qualifiedByName = "toBoolean")
     DTO01 DTO02_To_DTO01(DTO02 dto02);
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Named;

@Mapper
public interface MyMapStruct {
	 @Mapping(target = "field01", qualifiedByName = "toBoolean")
     DTO01 DTO02_To_DTO01(DTO02 dto02);

     @Named("toBoolean")
     default boolean intToBoolean(int value) {
    	 if (value >0) {
    		 return true;
    	 }else {
    		 return false;
    	 }
     }
     
}

这样的话两个Bean的field01字段就会按照自定义的逻辑来转换了

  • 30
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
引用的问题主要是关于在Eclipse使用MAP的问题。根据提供的引用内容,可以看出您遇到了ClassNotFoundException的错误。这个错误通常是由于找不到类的实现引起的。为了解决这个问题,您可以尝试以下几个步骤: 1. 确保您的项目已经正确引入了Mapstruct和相关的依赖库。可以通过在项目的pom.xml文件添加相应的依赖项来解决。确保您使用的是正确的版本和配置。 2. 检查您的编译设置,确保您的项目正确地引用了Mapstruct的注解处理器。在Eclipse,您可以通过右键单击项目,选择"Properties",然后选择"Java Compiler"来查看和配置注解处理器。确保您已经启用了"Enable annotation processing"选项,并且在"Factory Path"下添加了Mapstruct的引用。 3. 检查您的代码,确保您正确地使用Mapstruct的注解。Mapstruct使用注解来生成转换器的实现类,因此您需要在适当的位置标记您的转换器类和方法。确保您的转换器类上使用了`@Mapper`注解,并且您的方法上使用了适当的映射注解,如`@Mapping`。 4. 如果以上步骤都没有解决问题,您可以尝试重新构建和清理您的项目。有时候编译器可能会出现一些问题,重新构建和清理项目可以帮助解决一些编译错误。 希望以上提供的步骤可以帮助您解决在Eclipse使用Mapstruct的问题。如果问题仍然存在,请提供更多的详细信息,以便我们能够更好地帮助您解决问题。<span class="em">1</span> #### 引用[.reference_title] - *1* [eclipse支持mapstruct,解决ClassNotFoundException](https://blog.csdn.net/applecc/article/details/125384684)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值