作为一名新手 Java 程序员,您可能想知道如何构建一个大型应用程序,而无需使用大量可能使您筋疲力尽的类似代码。
在Java上构建 包含多个层的大型应用程序需要域、持久性和数据传输对象 (DTO) 等模型。应用程序通常由不同但相似的对象模型组成,其中数据可能相似但结构和目标不同。在执行大型应用程序时转换不同类型的数据或对象以用于业务决策或数据隐藏至关重要。
使用对象映射,可以更轻松地将一个模型转换为另一个模型,同时隔离单独的模型。
尽管将一个对象映射到另一个对象是很常见的,但由于这两个类具有相似或相同的映射属性,它通常可能是迭代且乏味的。幸运的是,有几个 Java 映射框架可以用来递归地将数据从一个对象复制到另一个对象。
但在继续讨论映射 框架之前,让我们先了解一下 Java 映射的基础知识。
什么是 JavaBean?
JavaBean 是将不同对象封装到一个对象或 bean 中的 Java 类。Bean 应该是可序列化的(即将对象状态转换为字节流),应该有一个公共的无参数构造函数,并且属性必须是私有的,具有公共的 getter 和 setter 方法。
让我们看一个显示 JavaBean 类的结构的示例。
- 打包我的包 ;
- 公共 类 学生 实现 java.io.Serializable{
- 私人 int id;
- 私有 字符串名称;
- 公共 学生(){}
- public void setId( int id){ this .id=id;}
- public int getId(){返回 id;}
- public void setName(String name){ this .name=name;}
- 公共 字符串 getName(){返回 名称;}
- }
现在访问 JavaBean,getter 和 setter 方法使用如下:
- 打包我的包 ;
- 公共 类 测试{
- 公共 静态 无效 主要(字符串参数[]){
- 学生 s=新 学生();//对象被创建
- s.setName(“安娜”); //设置对象的值
- System.out.println(e.getName());
- }}
尽管 JavaBeans 可以暴露给其他应用程序以重用软件组件,但 JavaBeans 是可变的(即可以在创建后更改),因此它们无法从不可变对象(如 Java 中的字符串在创建后无法更改)中受益。当你想要封装(隐藏)数据时,它需要一个 get 方法来返回它的值,并需要一个 set 方法来设置或更新它的值。但是,为每个属性创建 getter 和 setter 方法可能会导致在多个区域重复代码,几乎没有变化,也称为样板。
这就是 bean 映射框架在 项目开发中发挥作用的地方。
什么是 Bean 映射框架?
有时,由于非结构化、广泛的目标和非线性工作流程使应用程序更加复杂,构建企业级项目可能会很困难。此外,完成外部系统遗留组件的某些功能需要将具有相似结构的对象,如对域对象的外部服务响应和域对象转换为难以手动获取的外部服务请求。
让我们看看现实世界的场景,这些请求和响应对象可能包含许多列。使用手动代码将一个 bean/对象复制到另一个将需要大量代码行,例如destination.setABC(source.getABC()),它是递归且容易出错的。
如果您想克服编写类似代码行以将数据从一个 bean 复制到另一个的复杂性和重复性,那么 bean 映射框架非常有用,因为它提供了简单的配置和更少的代码行来简化您的工作。
Java 中用于映射的顶级框架
现在您已经知道 Java 中的 JavaBean 和 Bean 映射框架是什么以及为什么首先使用它们。现在是学习顶级 Java Bean 映射 框架的时候 了,您可以在处理下一个项目时使用这些框架进行映射。
dOOv
Domain Object Oriented Validation (dOOv) 是一种用于域模型验证和映射的 API。dOOv 使用代码生成、注释和类型安全的领域特定语言 (DSL) 来使映射和验证更容易、更快速。为您节省时间和精力。
dOOV 由 dOOv 核心、dOOv 生成器和 dOOv 断言组成,其中核心包含抽象语法树 (AST)、DST 和注释,生成器由用于字段信息和模型映射的代码生成器组成,断言包括 AssertJ 断言。
对于以下有关推荐框架的部分,我将提供框架的概述说明,然后编写代码段供您在准备好时开始使用。
- 标注域模型
公共类用户{
@TestPath(field = TestFieldId.FIRST_NAME, readable = "user first name")
private String firstName;
@TestPath(field = TestFieldId.LAST_NAME, readable = "user last name")
private String lastName;
@TestPath(field = TestFieldId.DATEOFDATE, 可读 = "用户出生日期")
private LocalDatebirthDate;
}
代码语言:txt复制
- 使用 userFirstName、userLastName 和 userDateIOfBirth 等元素生成 DSL 代码
- 编写和执行验证规则
ValidationRule 规则 = DOOV.when(userDateOfBirth.ageAt(today()).greaterOrEquals(18)).validate();
您必须在实例化模型中编写代码来执行它,其中实例化模型是真实实例的创建或抽象的特定实现,例如对象类。
代码语言:txt复制// 在模型上执行 DSL
DslModel model = new SampleModelWrapper(sampleModel);
结果 result = rule.executeOn(model);
if (result.isFalse()) {
// 在模型上做一些没有验证的事情
}
- 地图
要使用 dOOv 将对象与其他对象映射,您将编写代码为:
代码语言:txt复制MappingRegistry 映射 = 映射(
映射(userFirstName,userLastName)
.using(biConverter((first, last) -> first "" last))
.to(accountFullName),
map(userDateOfBirth)
.using(date -> Years.yearsBetween (日期, LocalDate.now()))
.to(accountAge));
代码语言:txt复制
然后可以使用两个实例化模型来执行映射代码。
代码语言:txt复制DslModel model1 = new SampleModelWrapper(sampleModel1);
DslModel model2 = new SampleModelWrapper(sampleModel2);
上下文上下文 = mappings.executeOn(model1, model2);
// 使用 model2 的新值做一些事情
- 测试验证规则
断言在 doov-assertions jar 中可用。由于 AssertJ 是必需的,因此您可以使用 assertThat 语法。
代码语言:txt复制ValidationRule 规则 = DOOV.when(userFirstName.isNotNull().or(userLastName.isNull())).validate();
代码语言:txt复制assertThat(rule).validates(model).hasFailedNodeEmpty();
映射器
JMapper 是 基于 Javassist的Java映射框架,它使用字节码操作进行快速映射。JMapper 以零内存消耗提供动态转换、关系映射和静态代码性能的优势。它接受两个类的输入,Destination(将创建或修改的实例)和 Source(包含数据的实例)。所以在映射之前,需要在Source和Destination之间配置一个类,然后调用 Get方法。
注解
代码语言:txt复制类目的地{
@JMap
字符串标识;
@JMap("SourceField")
字符串目标字段;
其他字符串;
// getter 和 setter
}
类源{
字符串ID;
字符串源字段;
其他字符串;
// getter 和 setter
}
要调用 GetDestination 方法,您将创建和使用 XML 文件,如下所示:
代码语言:txt复制<jmapper>
<class name="it.jmapper.bean.Destination">
<attribute name="id">
<value name="id"/>
</attribute>
<attribute name="destinationField">
<value name= "SourceField">
</attribute>
</class>
</jmapper>
为了执行,您将创建如下 API:
代码语言:txt复制JMapperAPI jmapperAPI = new JMapperAPI()
.add(mappedClass(Destination.class)
.add(attribute("id")
.value("id"))
.add(attribute("destinationField")
.value("SourceField")) );
代码语言:txt复制
地图结构
MapStruct 是用于高性能和类型安全的 JavaBeans 类映射器的最常用的 Java 注释处理器之一。它带有内置的转换和合理的默认值,在实现或配置特定行为时不会打扰您。
MapStruct 通过尽可能地自动化来简化映射。它生成 bean 映射编译时间以确保高性能、彻底的错误检查和快速反馈。
MapStruct 是一个注解处理器,插入到 Java 编译器中,可用于您首选的集成开发环境 (IDE) 或 Gradle 和 Maven 等命令行构建。
要使用 MapStruct,您需要定义映射器接口,声明所有必需的映射方法。
假设您有两个类,一个代表汽车,另一个代表数据传输对象 (DTO),如下所示:
- 汽车.java
公共类汽车{
私人字符串制作;
私人 int numberOfSeats;
私有 CarType 类型;
//构造函数、getter、setter等
}
- CarDTO.java
代码语言:txt复制公共类 CarDto {
私人字符串制作;
私人 int 座位数;
私有字符串类型;
//构造函数、getter、setter等
}
这两个类几乎相同,只是座位数的属性具有不同的名称,并且 Car 类中的枚举类型属性是 DTO 中的纯字符串。
要为 carDTO 创建映射器,映射器接口将定义为:
代码语言:txt复制@Mapper
公共接口 TestMapper {
TestMapper INSTANCE = Mappers.getMapper(TestMapper.class);
@Mapping(target = "seatCount", source = "numberOfSeats")
TestDto testToTestDto(Test test);
}
代码语言:txt复制
使用您为映射器创建的接口,可以以类型安全的方式轻松完成对象映射,如下所示:
代码语言:txt复制@Test
public void shouldMapCarToDto() {
//给定
汽车 car = new Car( "Morris", 5, CarType.SEDAN );
//当
CarDto carDto = CarMapper.INSTANCE.carToCarDto( car );
//然后
assertThat( carDto ).isNotNull();
assertThat( carDto.getMake() ).isEqualTo( "Morris" );
assertThat( carDto.getSeatCount() ).isEqualTo( 5 );
assertThat( carDto.getType() ).isEqualTo( "轿车" );
}
模型映射器
ModelMapper 是一个智能映射库,能够自动映射对象。它提供了一个简单的重构安全 API,并使用传统的方法来处理某些用例。
ModelMapper 是一个很棒的 Java Bean Mapper,因为它通过自动确定一个对象如何通过约定映射到另一个对象,从而使对象映射更容易,因此您不必担心手动映射。
您可以在 Maven 中设置 ModelMapper,如下所示:
代码语言:txt复制<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>3.0.0</version>
</dependency>
代码语言:txt复制
要使用 ModelMapper 将对象与其他对象映射,您可以将源和目标模型代码创建为:
源代码:
代码语言:txt复制// 假设每个类都有 getter 和 setter
class Order {
Customer customer;
地址 billingAddress;
}
类客户{
名称名称;
}
类名 {
字符串名;
字符串姓氏;
}
类地址{
字符串街道;
串城;
}
目的地代码:
代码语言:txt复制// 假设 getter 和 setter
类 OrderDTO {
String customerFirstName;
字符串客户姓氏;
字符串 billingStreet;
字符串计费城市;
}
要执行 ModelMapper 隐含映射,请使用以下内容:
代码语言:txt复制模型映射器模型映射器 = 新模型映射器();
OrderDTO orderDTO = modelMapper.map(order, OrderDTO.class);
在调用 map 方法时,将分析源模型和目标模型代码,以根据 匹配的配置 和策略识别属性简单性。只有在该数据映射到其他对象之后。
重映射
ReMap 是一个 Java 映射库,可帮助开发人员逐个属性地简化对象转换,同时减少映射器类的单元测试。
ReMap 可以通过 JCenter 和 Maven Central 轻松访问。以下是您将如何在应用内映射源和目标类型。
代码语言:txt复制Mapping.from(Customer.class) .to
(Person.class)
.omitInSource(Customer::getAddress)
.omitInDestination(Person::getBodyHeight)
.reassign(Customer::getTitle) .to
(Person::getSalutation)
.replace( Customer::getGender, Person::getGender)
.withSkipWhenNull(Gender::valueOf)
.mapper();
折花
Orika 是一个 JavaBean 到 Bean 映射框架,它迭代地将数据从一个对象复制到另一个对象。强烈建议在开发多层 Web 应用程序时使用它,因为 Orika 如何为 Java Bean 映射构建有效、全面和健壮的解决方案。
Orika 通过使用字节码生成器以最小的开销使 Java Bean 的映射更快。
要将两个 bean 或对象相互映射,首先要声明目标类和源类,如下所示:
代码语言:txt复制类 BasicPerson {
私有字符串名称;
私人年龄;
私人日期出生日期;
// getter/setter 省略
}
class BasicPersonDto {
private String fullName;
私人int currentAge;
私人日期出生日期;
// getter/setter 省略
}
接下来,将这两个类映射为:
代码语言:txt复制 mapperFactory.classMap(BasicPerson.class, BasicPersonDto.class) .field
("name", "fullName" ) .field ("age", "currentAge") .register();
如果您创建自定义 Mappers、Convertors 和 ObjectFactory 类型,也可以自定义 Orika 映射,其中映射器可用于将对象的属性应用于另一个对象;ObjectFactory 可用于在映射的上下文中构造实例,Converter 完全控制映射过程。为您的下一个项目制作一个高效的 Jave Bean Mapper。
代码语言:txt复制塞尔玛
Stupid Simple Statically Linked Mapper (AKA Selma) 是一个基于注解处理器的 Java bean 到 bean 映射器。它生成 Java 代码来处理字段到字段的映射,还可以作为运行时库来调用生成的映射器。
要查看 Selma 的运行情况,请按照给定的步骤操作:
代码语言:txt复制@Mapper
公共接口 SelmaMapper {
// 不可变映射
OutBean asOutBean(InBean source);
// 更新图
OutBean updateOutBean(InBean source, OutBean destination);
要使用 Selma 进行映射,我们将:
代码语言:txt复制 SelmaMapper 映射器 = Selma.mapper(SelmaMapper.class);
OutBean res = mapper.asOutBean(in);
// 或者
OutBean dest = dao.getById(42);
OutBean res = mapper.updateOutBean(in, dest);
// res 是 bean 目的地的值
推土机
Dozer 是一个 Java 映射框架,它使用 APL/XML 配置和注释将数据从一个对象复制到另一个对象。它是一个开源、健壮、灵活、可配置、可重用和通用的映射框架,支持 JavaBean 的复杂、简单、隐式、显式、双向和递归映射。如果您想避免在将数据从一个 bean 复制到另一个 bean 时使用不必要的代码,Dozer 是理想的选择。它不仅支持 bean 的映射,还可以自动转换数据类型以映射类与 DTO。
使用 Maven,您可以简单地通过以下方式在项目中添加 Dozer:
代码语言:txt复制<依赖>
<groupId>com.github.dozermapper</groupId>
<artifactId>推土机核心</artifactId>
<版本>6.5.2</版本>
</依赖>
创建源和目标类:
代码语言:txt复制<mapping>
<class-a>yourpackage.SourceClassName</class-a>
<class-b>yourpackage.DestinationClassName</class-b>
<field>
<a>yourSourceFieldName</a>
<b>yourDestinationFieldName</b>
</field>
</mapping>
并将这些类映射为:
代码语言:txt复制SourceClassName sourceObject = new SourceClassName();
sourceObject.setYourSourceFieldName("Dozer");
映射器映射器 = DozerBeanMapperBuilder.buildDefault();
DestinationClassName destObject = mapper.map(sourceObject,
DestinationClassName.class);
assertTrue(destObject.getYourDestinationFieldName().equals(sourceObject.getYourSourceFieldName()));
使用框架使 JavaBeans 映射更容易
在开发为满足大型企业的需求而量身定制的软件或 Web 应用程序时,[Java映射框架非常重要且至关重要
采用 Java Mapping 框架将更容易以更快的速度将数据对象从一个 bean 复制到另一个 bean,而且准确度更高,工作量最小。
这些顶级的 Java Mapping 框架,如 MapStruck、reMap、dozer 和 dOOv 将帮助您在未来获得专业优势。
关键要点:
- 使用对象映射,可以更轻松地将一个模型转换为另一个模型,同时隔离单独的模型。
- Bean 映射框架非常有用,因为它提供了简单的配置和更少的代码行来简化您的工作。
- dOOv、JMapper、MapStruct、ModelMapper、reMap、Orika、Selma 和 Dozer 等 Java Bean 映射框架可用于映射。
- 要映射两个对象,您需要创建源类和目标类。 s(sourceObject.getYourSourceFieldName()));
使用框架使 JavaBeans 映射更容易
在开发为满足大型企业的需求而量身定制的软件或 Web 应用程序时,[Java映射框架非常重要且至关重要
采用 Java Mapping 框架将更容易以更快的速度将数据对象从一个 bean 复制到另一个 bean,而且准确度更高,工作量最小。
这些顶级的 Java Mapping 框架,如 MapStruck、reMap、dozer 和 dOOv 将帮助您在未来获得专业优势。
关键要点:
- 使用对象映射,可以更轻松地将一个模型转换为另一个模型,同时隔离单独的模型。
- Bean 映射框架非常有用,因为它提供了简单的配置和更少的代码行来简化您的工作。
- dOOv、JMapper、MapStruct、ModelMapper、reMap、Orika、Selma 和 Dozer 等 Java Bean 映射框架可用于映射。
- 要映射两个对象,您需要创建源类和目标类。
- Java Bean 框架可以通过 Maven 和 Gradle 等命令行构建轻松访问