一、Object mapping 的技术分类:

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

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



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

MapStruct 与 Selma的对比: https://java.libhunt.com/project/mapstruct/vs/selma

与 ModelMapper的对比:https://java.libhunt.com/project/mapstruct/vs/modelmapper

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

二、Maven依赖与配置:

    <properties>
<java.version>1.8</java.version>
<org.mapstruct.version>1.2.0.Final</org.mapstruct.version>
</properties>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${java.encoding}</encoding>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>

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

        <dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
<scope>provided</scope>
</dependency>

三、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的属性与方法:

  1. @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);
}

原文地址 https://blog.csdn.net/paincupid/article/details/71247255

Java 实体-实体的映射框架的更多相关文章

  1. 开源实体映射框架EmitMapper介绍

    开源实体映射框架EmitMapper介绍   综述       EmitMapper是一个开源实体映射框架,地址:http://emitmapper.codeplex.com/.       Emit ...

  2. xml文档的解析并通过工具类实现java实体类的映射:XML工具-XmlUtil

    若有疑问,可以联系我本人微信:Y1141100952 声明:本文章为原稿,转载必须说明 本文章地址,否则一旦发现,必追究法律责任 1:本文章显示通过 XML工具-XmlUtil工具实现解析soap报文 ...

  3. [LINQ2Dapper]最完整Dapper To Linq框架(三)---实体类关系映射

    此特性需要安装Kogel.Dapper.Mssql或者Oracle 3.06及以上版本,实体类层需要安装Kogel.Dapper.Extension 3.06及以上版本 目录 [LINQ2Dapper ...

  4. Hibernate JPA实体继承的映射(一) 概述

    http://www.cnblogs.com/yingsong/p/5179975.html   注:文章中据说的实体指的是被@Entity注解的类. JPA中对象关系映射通常情况下是一个实体对应一个 ...

  5. Eclipse从数据库逆向生成Hibernate实体类和映射文件(Eclipse插件系列之HibernateTools)

    ♣下载安装Eclipse插件(HibernateTools) ♣Eclipse连接数据库(Mysql5.7) ♣新建hibernate.properties和hibernate.cfg.xml文件 ♣ ...

  6. 将JSON数据转换成JAVA的实体类

    思路:首先将JSON格式的数据转换成JSONObject,然后将JSONObject转换成Java的实体类(其中类属性包括List等类型) Java实体类: SearchFilter 类 1 publ ...

  7. 反向生成hibernate实体类和映射文件

    工欲善其事,必先利其器.我们可以使用IDE来根据数据库中的表反向生成实体类和映射文件,虽然这些东西手写也并不是难度很大,但是如果存在大量的简单工作需要我们做,也会显得很麻烦. 写在前面 我们反向生成的 ...

  8. 高速创建和mysql表相应的java domain实体类

    今天创建了一个表有十几个字段,创建完之后必定要写一个与之相应的java domain实体类. 这不是反复的工作吗?为什么不先把这个表的全部的字段查出来,然后放到linux环境下,用sed工具在每一行的 ...

  9. automapper实体中的映射和聚合根中的使用

    一,如下例子: using AutoMapper; using System; using System.Collections.Generic; using System.Linq; using S ...

  10. ASP.NET Core搭建多层网站架构【5-网站数据库实体设计及映射配置】

    2020/01/29, ASP.NET Core 3.1, VS2019, EntityFrameworkCore 3.1.1, Microsoft.Extensions.Logging.Consol ...

随机推荐

  1. [ HEOI 2016 ] 树

    \(\\\) Description 给出一颗树,开始只有 \(1\) 号节点有标记. \(\ C\ x\) 对 \(x\) 号节点打标记 \(\ Q\ x\) 查询 \(x\) 号节点深度最深的有标 ...

  2. QQ面板拖拽(慕课网DOM事件探秘)(上)

    QQ面板拖拽,效果如图 JavaScript代码如下: function getByClass(clsName, parent) { var oParent = parent ? document.g ...

  3. Vue 2.0入门基础知识之内部指令

    1.Vue.js介绍 当前前端三大主流框架:Angular.React.Vue.React前段时间由于许可证风波,使得Vue的热度蹭蹭地上升.另外,Vue友好的API文档更是一大特色.Vue.js是一 ...

  4. ie 导出不行,不兼容问题,或只出现后缀文件无法识别

    // 下载模板 @RequestMapping("/download") @ResponseBody public ResponseEntity<byte[]> dow ...

  5. sql地址寻路算法(省市区路)

    最近无意翻开4年前做过的一个功能,就是搜集全国各城市各个区(县)的路(XX路.XX道.XX街.XX镇.XX乡.XX屯.XX村.XX社).众所周知,我们都可以在网上找到省.市.区(县)这三级联动的数据, ...

  6. [转] 学习,思维三部曲:WHAT、HOW、WHY(通过现象看本质)

    https://www.douban.com/note/284947308/?type=like 学习技术的三部曲:WHAT HOW WHY 我把学习归类为三个步骤:What.How.Why.经过我对 ...

  7. shell 数值比较和字符串比较

    1. 数值比较 -eq        是否相等(equal) -gt         是否大于(greater than) -ge       是否大于等于(greater and equal tha ...

  8. Keil Debug (printf) Viewer

    Debug (printf) Viewer Home » µVision Windows » Debug (printf) Viewer The Debug (printf) Viewer windo ...

  9. ES6对象和数组解构

    解构可以避免在对象赋值时再生成多余的中间变量: function foo() { return [1,2,3]; } let arr = foo(); // [1,2,3] let [a, b, c] ...

  10. 安卓获取数据demo出现的问题

    时间戳是long型的数据,但其他数据都是float型,但AsyncTask要求是统一数据类型.这样我就不能把时间戳放进AsyncTask里面进行处理,我就在doInBackground中获取时间戳然后 ...