Dozer 对象的"搬运工"

前言:项目中,经常会遇到各层对象之间相互进行值传递的过程,如在数据据持久层有一持久类EntityA,在视图层可能会变为ViewA,通常情况下,这两个类的属性 名称 、类型都是一致的,

    在两个对象传值的过程中,有几种办法:

    1.最基本的set(),get()方法,当对象的属性有很多时,会产生大量的代码

    2.apache的common-beanutils.jar 下 BeanUtils().copyProperties(obj1,obj2)

    3.dozer

本文主要介绍dozer的用法

1.简介
    dozer是一种JavaBean的映射工具,类似于apache的BeanUtils。但是dozer更强大,它可以灵活的处理复杂类型之间的映射。不但可以进行简单的属性映射、复杂的类型映射、

    双向映射、递归映射等,并且可以 通过XML配置文件进行灵活的配置。

    使用Dozer映射复杂类型:1. 数据类型不一致。 2. 级联映射。 3. 自定义映射。

   Dozer其实底层使用了现成的BeanUtil,通过反射来映射,况且Dozer应用了Cache技术,应该比通过BeanUtils映射性能要好点。所以一般的应用应该不存在性能问题。

2.配置

  1.添加spring相关jar(如果单独使用可以不需要配置)

  2.添加dozer与spring集成jar(如果单独使用dozer,可以不用dozer-spring,以下所有案例都是与将dozer与spring集成使用)

pom依赖:

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

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

 spring配置文件:

 <!-- 自动扫描的包名 -->
    <context:annotation-config/>
    <context:component-scan base-package="dozer.*"/>

    <bean id="mapper" class="org.dozer.spring.DozerBeanMapperFactoryBean">
        <property name="mappingFiles" value="classpath*:/*-mapper.xml"/>  //此处的mapper配置文件是用来处理复杂类型的转换使用
    </bean>

3.案列

  1.基本属性映射:只会映射属性名相同的值,如果属性名不同,则不会处理

       只要属性名相同,基本数据类型之间、String与基本数据类型之间都双向转换

    如:int a  <--> double a;   String b <-->float b;

   UserEntity:

public class UserEntity {
    private Long id;
    private String name;
    private int age;
    private String password;
    private Date date;
    private String map;
    ...get()  ...set()
    ...XXX
}

   UserVo:

public class UserVO {
    private Long id;
    private String userName;
    private double age;
    private String password;
    private String createDate;
    private float map;
  ...XXX get() ...set()
}

   测试类:

 @Test
    public void  testDozer(){
        UserEntity entity=new UserEntity(2L,"admin",13,"admin",new Date(),"23.7");
        UserVO userVO=new UserVO();
        mapper.map(entity,userVO);
        System.out.println(userVO);
    }

   结果:

       

   结果对比,如果属性名不一直,则不会处理

  2.对于1中出现属性不一致的情况,我们仍然想要进行值传递,该怎么办呢?这时就要用到<property name="mappingFiles" value="classpath*:/*-mapper.xml"/>配置文件

    添加user-mapper.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns="http://dozer.sourceforge.net"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://dozer.sourceforge.net
          http://dozer.sourceforge.net/schema/beanmapping.xsd">
    <!--<configuration>-->
        <!--<date-format>yyyy-MM-dd HH:mm:ss</date-format>-->
    <!--</configuration>-->

    <mapping >
        <class-a>entity.UserEntity</class-a>
        <class-b>pojo.UserVO</class-b>
        <field>
            <a>name</a>
            <b>userName</b>
        </field>
        <field>
            <a>date</a>
            <b>createDate</b>
        </field>
    </mapping>
</mappings>

    运行结果:

    

  每个属性的值都已传递过来,但是注意途中红框中的内容,Date 类型 转 String 类型的时候,String createDate的值并不是我们期望的格式,我们期望将其 装换成 "yyyy-MM-dd HH:mm:ss"格式,或者其他自定义的日期格式,那该怎么办呢? 请看下一点

  3.对于2中的问题,String  to Date 或 Date  to String 转换 这里有三种方式可以解决:

    ①在属性匹配 上修改配置 使用dozermapper中field的date-format属性

  <mapping >
        <class-a>entity.UserEntity</class-a>
        <class-b>pojo.UserVO</class-b>
        <field>
            <a>name</a>
            <b>userName</b>
        </field>
        <field>
            <a date-format="yyyy-MM-dd HH:mm:ss">date</a>
            <b>createDate</b>
        </field>
    </mapping>

    ②在类匹配 上修改配置,使用mapping中的date-format属性

    <mapping date-format="yyyy-MM-dd HH:mm:ss">
        <class-a>entity.UserEntity</class-a>
        <class-b>pojo.UserVO</class-b>
        <field>
            <a>name</a>
            <b>userName</b>
        </field>
        <field>
            <a>date</a>
            <b>createDate</b>
        </field>
    </mapping>

    ③在全局属性上 ,修改配置,使用configuration标签下的date-format标签 

<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns="http://dozer.sourceforge.net"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://dozer.sourceforge.net
          http://dozer.sourceforge.net/schema/beanmapping.xsd">

    <configuration>
        <date-format>yyyy-MM-dd HH:mm:ss</date-format>
    </configuration>

    <mapping>
        <class-a>entity.UserEntity</class-a>
        <class-b>pojo.UserVO</class-b>
        <field>
            <a>name</a>
            <b>userName</b>
        </field>
        <field>
            <a>date</a>
            <b>createDate</b>
        </field>
    </mapping>
</mappings>

    结果:

  

   4.如果在两个对象间传值,不想要对某个属性赋值,可以使用 field-exclude标签

<mapping>
        <class-a>entity.UserEntity</class-a>
        <class-b>pojo.UserVO</class-b>
        <field>
            <a>name</a>
            <b>userName</b>
        </field>
        <field>
            <a>date</a>
            <b>createDate</b>
        </field>
        <field-exclude>
            <a>unpass</a>
            <b>unpass</b>
        </field-exclude>
    </mapping>

       

  5.级联映射  UserEntity中有个Colleage对象,而UserVO中有个属性schoolName指向UserEntity.Colleage.Name

     <field>
            <a>colleage.name</a>
            <b>schoolName</b>
        </field>

 至此,dozer最基本"搬运"方法已经介绍完毕,后续会继续学习 其他标签的用法 以及 集合类型的属性匹配。

 

posted @ 2016-04-08 16:05  wandy丶  阅读(1574)  评论(2编辑  收藏  举报