当前位置: 代码网 > it编程>编程语言>Java > 在Eclipse中使用MapStruct

在Eclipse中使用MapStruct

2024年08月03日 Java 我要评论
MapStruct和Dozer等Bean复制工具的区别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字段就会按照自定义的逻辑来转换了

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com