Dozerbean映射示例

Dozer是一个功能强大的库,可以在我们希望将数据从一个bean复制到另一个bean的同时,避免了很多不必要的代码。主要是bean到bean的映射器,将数据从一个Java对象递归地复制到另一个Java对象–按属性。

当我们处理深层嵌套的复杂Java Bean(在大型企业应用程序中很容易看到)时,我们意识到它的全部功能。将数据从一个这样的大bean复制到另一个类似的bean可能需要数百行代码

目录

1.什么是bean映射器及其重要意义
2。 Dozer Maven依赖关系
3.简单的Bean映射示例
4.使用XML映射文件的
Dozer映射5.使用注解的Dozer映射
6。 Dozer自定义转换器示例
7。 Dozer BeanMappingBuilder示例
8。 Spring DozerBeanMapper示例
9.总结

1.什么是bean映射器及其重要性

如今,所有企业项目本质上都是相当复杂的,通常要完成某些业务功能,我们需要将外部系统称为传统组件,这需要对结构或多或少相同的不同类型的对象进行转换,例如将域对象转换为外部服务请求/外部服务对域对象的响应等。

现在在现实世界中,那些请求/响应对象可能包含大量字段,因此为了将数据从一个对象复制到另一个对象,如果我们需要为此手动编写代码,则将需要大量的代码,例如destination.setXYZ(source.getXYZ())重复的代码从本质上讲,容易出错,例如缺少字段,匹配错误等。

在这种情况下,Bean映射器就变得生动起来,并且通过一些简单的配置和几行代码就可以非常方便地将值从一个bean复制到另一个bean。今天,我们将学习Dozerbean映射器,并以Spring和非Spring方式进行演示。

2.Dozer的Maven依赖

要使用Dozer,我们需要在pom.xml我们的Maven项目中添加以下依赖项。

<dependency>
    <groupId>net.sf.dozer</groupId>
    <artifactId>dozer</artifactId>
    <version>5.5.1</version>
</dependency>

3.DozerBean映射示例

我们有两个类,ClassAClassB三个字段。字段名称相似,但其数据类型可能不同。在这里,Dozer将能够自动处理它,而无需任何特殊操作。

ClassA.java
package com.example.howtodoinjava.dozer.simple;
public class ClassA {
    private String name;
    private String age;
    private String address;
    //Getters and Setters
}
ClassB.java
package com.example.howtodoinjava.dozer.simple;
public class ClassB {
    private String name;
    private int age;
    private String address;
    //Getters and Setters
}

一个简单的Dozer Bean映射示例。

SimpleExample.java
package com.example.howtodoinjava.dozer.simple;
import org.dozer.DozerBeanMapper;
public class SimpleExample
{
    public static void main(String[] args)
    {
        ClassA classA = new ClassA();
        classA.setAddress("India");
        classA.setName("Sajal");
        classA.setAge("50");
        ClassB classB = new DozerBeanMapper().map(classA, ClassB.class);
        System.out.println(classB);
    }
}

程序输出。

安慰
Output: ClassB toString after applying Dozer transformation : ClassB [name=Sajal, age=50, address=India]

4.使用XML映射的DozerBean映射

在此示例中,SourceObject包含Student对象列表和其他几个字段。同样,DestinationObject也有一个StudentVO对象列表以及一些其他简单字段。我们将使用XML映射文件将的属性映射SourceObjectDestinationObject

SourceObject.java
package com.example.howtodoinjava.dozer.models;
import java.util.ArrayList;
import java.util.List;
public class SourceObject {
    private String name;
    private String address;
    List<Student> students;
    //Getters and Setters
}
Student.java
package com.example.howtodoinjava.dozer.models;
public class Student {
    String name;
    String batch;
    String address;
    //Getters and Setters
}
DestinationObject.java
package com.example.howtodoinjava.dozer.models;
import java.util.ArrayList;
import java.util.List;
public class DestinationObject {
    
    private String name;
    private String address;
    List<StudentVO> pupils;
    //Getters and Setters
}
StudentVO.java
package com.example.howtodoinjava.dozer.models;
public class StudentVO {
    String name;
    String batchName;
    String homeAddress;
    //Getters and Setters
}

Bean映射xml文件如下。

student-mapper.xml
<?xml version="1.0" encoding="UTF-8"?>
    xsi:schemaLocation="http://dozer.sourceforge.net
      http://dozer.sourceforge.net/schema/beanmapping.xsd">
      
     <mapping>
        <class-a>com.example.howtodoinjava.dozer.models.SourceObject</class-a>
        <class-b>com.example.howtodoinjava.dozer.models.DestinationObject</class-b>
        <field>
            <a>students</a>
            <b>pupils</b>
        </field>
    </mapping>
    <mapping>
        <class-a>com.example.howtodoinjava.dozer.models.Student</class-a>
        <class-b>com.example.howtodoinjava.dozer.models.StudentVO</class-b>
        <field>
            <a>batch</a>
            <b>batchName</b>
        </field>
        <field>
            <a>address</a>
            <b>homeAddress</b>
        </field>
    </mapping>
</mappings>

有关详细参考,您可以遵循Dozer用户指南

演示程序
package com.example.howtodoinjava.dozer.demo.withoutspring;
import java.util.Arrays;
import org.dozer.DozerBeanMapper;
import com.example.howtodoinjava.dozer.models.DestinationObject;
import com.example.howtodoinjava.dozer.models.SourceObject;
import com.example.howtodoinjava.dozer.models.Student;
public class Demo {
    public static void main(String[] args)
    {
        DozerBeanMapper dozerBeanMapper = new DozerBeanMapper();
        SourceObject sourceObject = new SourceObject();
        sourceObject.setName("Sajal");
        sourceObject.setAddress("India");
        sourceObject.getStudents().add(new Student("S1""C1""diffField1"));
        sourceObject.getStudents().add(new Student("S2""C2""diffField2"));
        sourceObject.getStudents().add(new Student("S3""C3""diffField3"));
        dozerBeanMapper.setMappingFiles(Arrays.asList("mappings\\student-mapper.xml"));
        DestinationObject destinationObject = dozerBeanMapper.map(sourceObject, DestinationObject.class);
        System.out.println(destinationObject);
    }
}

程序输出。

安慰
DestinationObject [name=Sajal, address=India, pupils=[
 StudentVO [name=S1, batchName=C1, homeAddress=diffField1],
 StudentVO [name=S2, batchName=C2, homeAddress=diffField2],
 StudentVO [name=S3, batchName=C3, homeAddress=diffField3]]
]

5.Dozerbean映射注解– @Mapping

Dozer的配置也可以@Mapping通过Dozer提供的注解来完成。可以将其放在映射的属性本身上,从而减少代码量。

当前,它@Mapping是Dozer提供的唯一注解,它有助于非常简单的属性映射。如果您遇到任何复杂的问题,请使用XML映射或自定义转换器。

在此示例中,我修改了XML映射演示中使用的类,以保持方法的可比性。

SourceObject.java
package com.example.howtodoinjava.dozer.models;
import java.util.ArrayList;
import java.util.List;
public class SourceObject {
    private String name;
    private String address;
    @Mapping("pupils")
    List<Student> students;
    //Getters and Setters
}
Student.java
package com.example.howtodoinjava.dozer.models;
public class Student {
    String name;
    @Mapping("batchName")
    String batch;
    @Mapping("homeAddress")
    String address;
    //Getters and Setters
}
DestinationObject.java
package com.example.howtodoinjava.dozer.models;
import java.util.ArrayList;
import java.util.List;
public class DestinationObject {
    
    private String name;
    private String address;
    List<StudentVO> pupils;
    //Getters and Setters
}
StudentVO.java
package com.example.howtodoinjava.dozer.models;
public class StudentVO {
    String name;
    String batchName;
    String homeAddress;
    //Getters and Setters
}

Dozer @Mapping注解示例。

AnnotationExample.java
import org.dozer.DozerBeanMapper;
public class AnnotationExample {
    public static void main(String[] args)
    {
        SourceObject sourceObject = new SourceObject();
        sourceObject.setName("Sajal");
        sourceObject.setAddress("India");
        sourceObject.getStudents().add(new Student("S1""C1""diffField1"));
        sourceObject.getStudents().add(new Student("S2""C2""diffField2"));
        sourceObject.getStudents().add(new Student("S3""C3""diffField3"));
        
        DestinationObject targetObj = new DozerBeanMapper().map(sourceObject, DestinationObject.class);
        System.out.println("DestinationObject : " + targetObj);
    }
}

程序输出。

安慰
DestinationObject [name=Sajal, address=India, pupils=[
 StudentVO [name=S1, batchName=C1, homeAddress=diffField1],
 StudentVO [name=S2, batchName=C2, homeAddress=diffField2],
 StudentVO [name=S3, batchName=C3, homeAddress=diffField3]]
]

6.Dozer定制转换器示例

到现在为止,我们看到了Dozer如何帮助我们将字段值从源对象复制到目标对象。但是,在现实生活中,我们可能需要在转换值之前和之后添加一些逻辑。在这些情况下,Dozer提供的自定义转换器就可以发挥作用。我们可以在这些转换器中添加任何某种转换逻辑。

在此示例中,从源复制到目标时,我们要将字符串值转换为UPPERCASE。让我们看看如何实现这一目标。

SourceObject.java
package com.example.howtodoinjava.dozer.converters;
public class SourceObject {
    
    private String fullname;
    //Getters, Setters, Constrctors and toString Method
}
DestinationObject.java
package com.example.howtodoinjava.dozer.converters;
public class DestinationObject {
    
    private String fullname;
    //Getters, Setters, Constrctors and toString Method
}

任何自定义转换器都必须DozerConverter使用源和目标作为参数进行扩展。然后,我们需要重写convertFrom(source, destination)convertTo(source, destination)方法来添加逻辑以进行正向和反向转换。

UpperCaseConverter.java
import org.apache.commons.lang3.StringUtils;
import org.dozer.DozerConverter;
public class UpperCaseConverter extends DozerConverter<String, String>
{
    public UpperCaseConverter() {
        super(String.class, String.class);
    }
    @Override
    public String convertFrom(String source, String destination) {
        if (source != null) {
            return StringUtils.upperCase(source);
        }
        return null;
    }
    @Override
    public String convertTo(String source, String destination) {
        //No Modification when copy backward
        return convertTo(source, destination);
    }
}

现在我们需要在Dozer中注册该转换器,我们将在映射文件中进行如下操作。这里有几个变体,例如我们可以在全局声明部分或字段部分等中注册自定义转换器。

有关详细信息,请访问官方的Dozer文档

custom-converter-spring-mapping.xml
<?xml version="1.0" encoding="UTF-8"?>
    xsi:schemaLocation="http://dozer.sourceforge.net
      
    <mapping>
        <class-a>com.example.howtodoinjava.dozer.converters.SourceObject</class-a>
        <class-b>com.example.howtodoinjava.dozer.converters.DestinationObject</class-b>
        <field custom-converter="com.example.howtodoinjava.dozer.converters.UpperCaseConverter" custom-converter-param="fullname">
            <a>fullname</a>
            <b>fullname</b>
        </field>
    </mapping>
</mappings>

现在,如前所述,在Spring注册Dozerbean映射器。

custom-converter-spring-beans.xml
<?xml version="1.0" encoding="UTF-8"?>
    
    
    <bean id="dozerBeanMapper" class="org.dozer.DozerBeanMapper">
        <property name="mappingFiles">
            <list>
                <value>custom-converter-mapping.xml</value>
            </list>
        </property>
    </bean>
    
</beans>

Dozer自定义转换器示例程序。

CustomConverterTest.java
import org.dozer.DozerBeanMapper;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class CustomConverterTest {
    @SuppressWarnings("resource")
    public static void main(String[] args) {
        SourceObject sourceClassForConverters = new SourceObject("Saigon");
        
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("custom-converter-spring-beans.xml");
        DozerBeanMapper beanMapper = (DozerBeanMapper) applicationContext.getBean("dozerBeanMapper");
        
        DestinationObject destinationClassForConverters = beanMapper.map(sourceClassForConverters, DestinationObject.class);
        
        System.out.println(destinationClassForConverters);
    }
}

程序输出。

安慰
DestinationObject [fullname=LOKESH GUPTA]

7。 Dozer BeanMappingBuilder示例

到目前为止,我们学会了使用xml和注解配置来配置Dozer。现在,我们将学习如何使用BeanMappingBuilder类以编程方式声明Dozer映射。

在此示例中,我们创建了两个类SourceObjectDestinationObject。两者都具有单个字段date,只是它们的数据类型不同。

SourceObject.java
public class DestinationObject {
    
    String date;
}
DestinationObject.java
import java.util.Date;
public class DestinationObject {
    
    Date date;
}

Java程序显示DozerBeanMappingBuilder示例。

BeanMappingBuilderExample.java
package com.example.howtodoinjava.dozer.api;
import org.dozer.DozerBeanMapper;
import org.dozer.loader.api.BeanMappingBuilder;
import org.dozer.loader.api.TypeMappingOptions;
public class BeanMappingBuilderExample {
    public static void main(String[] args) {
        //Bean mapping
        BeanMappingBuilder beanMappingBuilder = new BeanMappingBuilder() {
            @Override
            protected void configure() {
                String dateFormat = "MM/dd/yyyy HH:mm";
                mapping(SourceObject.class
                        DestinationObject.class
                        TypeMappingOptions.wildcard(true),
                        TypeMappingOptions.dateFormat(dateFormat)).
                        fields("date""date");
            }
        };
        //Example
        DozerBeanMapper dozerBeanMapper = new DozerBeanMapper();
        dozerBeanMapper.addMapping(beanMappingBuilder);
        SourceObject src = new SourceObject();
        src.setDate("08/06/2017 11:45");
        
        DestinationObject dest = dozerBeanMapper.map(src, DestinationObject.class);
        
        System.out.println("DestinationObject : " + dest);
    }
}

程序输出。

安慰
DestinationObject : DestinationObject [date=Sun Aug 06 11:45:00 IST 2017]

8。 Spring DozerBeanMapper示例

如果您的项目中有Spring框架,则可以创建创建的org.dozer.DozerBeanMapperbean并使用它,如下例所示。

applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
    
    <bean id="dozerBeanMapper" class="org.dozer.DozerBeanMapper">
        <property name="mappingFiles">
            <list>
                <value>mappings/student-mapper.xml</value>
            </list>
        </property>
    </bean>
    
</beans>

如何使用DozerBeanMapper映射 Bean。

DemoWithDozerBeanMapper.java
package com.example.howtodoinjava.dozer.demo.withspring;
import org.dozer.DozerBeanMapper;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.example.howtodoinjava.dozer.models.DestinationObject;
import com.example.howtodoinjava.dozer.models.SourceObject;
import com.example.howtodoinjava.dozer.models.Student;
public class DemoWithDozerBeanMapper {
    public static void main(String[] args) {
        SourceObject sourceObject = new SourceObject();
        sourceObject.setName("Sajal");
        sourceObject.setAddress("India");
        sourceObject.getStudents().add(new Student("S1""C1""diffField1"));
        sourceObject.getStudents().add(new Student("S2""C2""diffField2"));
        sourceObject.getStudents().add(new Student("S3""C3""diffField3"));
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
        DozerBeanMapper beanMapper = (DozerBeanMapper) applicationContext.getBean("dozerBeanMapper");
        DestinationObject destinationObject = beanMapper.map(sourceObject, DestinationObject.class);
        
        System.out.println(destinationObject);
    }
}

程序输出。

安慰
DestinationObject [name=Sajal, address=India, pupils=[
 StudentVO [name=S1, batchName=C1, homeAddress=diffField1],
 StudentVO [name=S2, batchName=C2, homeAddress=diffField2],
 StudentVO [name=S3, batchName=C3, homeAddress=diffField3]]
]

请注意,Dozer已成功将所有字段从复制SourceObjectDestinationObject类。

9.总结

因此,在本文中dozer tutorial,我们了解了如何配置Dozer以及如何将Dozer用于简单的用例。我们还看到了如何创建Dozer自定义转换器,以及如何使用BeanMappingBuilder以API样式声明映射。

saigon has written 1445 articles

Leave a Reply