java 对象映射_Java 实体-实体的映射框架

本文介绍了MapStruct在对象映射中的应用,对比了运行期反射调用与编译期生成代码的性能差异,推荐了MapStruct作为优秀选择。详细阐述了MapStruct的Maven依赖配置、基本使用方法以及@Mapper注解的componentModel属性。同时,讨论了MapStruct与Lombok结合使用时的注意事项,并给出了多对象映射的示例。
摘要由CSDN通过智能技术生成

一、Object mapping 的技术分类:

运行期 反射调用set/get 或者是直接对成员变量赋值 。 该方式通过invoke执行赋值 *,实现时一般会采用beanutil, Javassist等开源库。这类的代表:Dozer,ModelMaper

编译期 动态生成set/get代码的class文件 ,在运行时直接调用该class文件。* 该方式实际上扔会存在set/get代码,只是不需要自己写了。 这类的代表:MapStruct,Selma,Orika ### 主要框架性能对比: 每秒钟执行的object mapping越多越好。

46b10fd88287d3bdf14fa46cfae6d63b.png

明显可以看出通过在运行期进行反射的方式执行,性能远不如编译器生成class的方式;

综合比较性能、问题排查、文档、成熟度、扩展性等因素来考虑,MapStruct 是一个不错的选择;

二、Maven依赖与配置:

1.8

1.2.0.Final

org.mapstruct

mapstruct-jdk8

${org.mapstruct.version}

org.apache.maven.plugins

maven-compiler-plugin

3.5.1

${java.version}

${java.version}

${java.encoding}

org.mapstruct

mapstruct-processor

${org.mapstruct.version}

或者可以两个都写成依赖,不需要写成maven插件的形式,后面的依赖用于生成运行期的class实现类,如下:

org.mapstruct

mapstruct-processor

${org.mapstruct.version}

provided

三、MapStruct的基本使用:

@Mapper(componentModel = "spring")

public interface MonitorAppGroupIdcDTOMapper {

MonitorAppGroupIdcDTOMapper MAPPER = Mappers.getMapper(MonitorAppGroupIdcDTOMapper.class);

void mapping(MonitorAppGroupIdcDTO source, @MappingTarget MonitorAppGroupIdcDTO dest);

}

编译后生成的部分代码结构:

@Component

public class MonitorAppGroupIdcDTOMapperImpl implements MonitorAppGroupIdcDTOMapper {

public MonitorAppGroupIdcDTOMapperImpl() {

}

public void mapping(MonitorAppGroupIdcDTO source, MonitorAppGroupIdcDTO dest) {

if(source != null) {

dest.setId(source.getId());

dest.setGmtCreate(source.getGmtCreate());

...

}

}

}

可以看出MapStruct还需要依赖对象的get/set方法,有时候编写一堆的get/set方法看上去很不美观,期望能通过自动生成的方式插入get/set方法,其解决方案是使用lombok。mapstrcut官网也有二者结合的例子: https://github.com/mapstruct/mapstruct/issues/510 Lombok带来的问题是,如果我们期望通过公有的get/set方法范围私有属性时,IDE会提示方法不存在,这个时候我们可以下载安装Intellij Idea中的”Lombok plugin”来解决,但是这种方案带来了一定的繁琐性。比较好的方式是,对于DO或者DTO中的属性,如果属性为私有属性,需要通过get/set方法来访问的,那么就手工生成get/set方法,如果属性本身为共有属性的,那么就可以借助Lombok来自动生成get/set方法了。

四、MapStruct的属性与方法:

@Mapper注解的componentModel属性

componentModel 属性用于指定自动生成的接口实现类的组件类型。这个属性支持四个值:

default: 这是默认的情况,mapstruct不使用任何组件类型, 可以通过Mappers.getMapper(Class)方式获取自动生成的实例对象。

cdi: the generated mapper is an application-scoped CDI bean and can be retrieved via @Inject

spring: 生成的实现类上面会自动添加一个@Component注解,可以通过Spring的 @Autowired方式进行注入

jsr330: 生成的实现类上会添加@javax.inject.Named 和@Singleton注解,可以通过 @Inject注解获取。

五、下面我们先来看下代码,多对象映射如下所示:

@Mapper(componentModel = "spring")

//@Mapper

public interface GoodInfoMapper

{

//public static GoodInfoMapper MAPPER = Mappers.getMapper(GoodInfoMapper.class);

@Mappings({

@Mapping(source = "type.name",target = "typeName"),

@Mapping(source = "good.id",target = "goodId"),

@Mapping(source = "good.title",target = "goodName"),

@Mapping(source = "good.price",target = "goodPrice")

})

public GoodInfoDTO from(GoodInfoBean good, GoodTypeBean type);

}

该资源包含源代码 易看易懂 其实就是一发射机制 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。其中LEAD/LEAD++ 、OpenC++ 、MetaXa和OpenJava等就是基于反射机制的语言。最近,反射机制也被应用到了视窗系统、操作系统和文件系统中。 反射本身并不是一个新概念,它可能会使我们联想到光学中的反射概念,尽管计算机科学赋予了反射概念新的含义,但是,从现象上来说,它们确实有某些相通之处,这些有助于我们的理解。在计算机科学领域,反射是指一类应用,它们能够自描述和自控制。也就是说,这类应用通过采用某种机制来实现对自己行为的描述(self-representation)和监测(examination),并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。可以看出,同一般的反射概念相比,计算机科学领域的反射不单单指反射本身,还包括对反射结果所采取的措施。所有采用反射机制的系统(即反射系统)都希望使系统的实现更开放。可以说,实现了反射机制的系统都具有开放性,但具有开放性的系统并不一定采用了反射机制,开放性是反射系统的必要条件。一般来说,反射系统除了满足开放性条件外还必须满足原因连接(Causally-connected)。所谓原因连接是指对反射系统自描述的改变能够立即反映到系统底层的实际状态和行为上的情况,反之亦然。开放性和原因连接是反射系统的两大基本要素。13700863760 Java中,反射是一种强大的工具。它使您能够创建灵活的代码,这些代码可以在运行时装配,无需在组件之间进行源代表链接。反射允许我们在编写与执行时,使我们的程序代码能够接入装载到JVM中的类的内部信息,而不是源代码中选定的类协作的代码。这使反射成为构建灵活的应用的主要工具。但需注意的是:如果使用不当,反射的成本很高。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值