Dozer更加灵活给对象赋值,对象间拷贝

来源:互联网 发布:非常网络 易中天 编辑:程序博客网 时间:2024/05/01 13:51

Spring Dozer 使用:

使用Dozer映射复杂类型:

      1. 数据类型不一致。

      2. 级联映射。

      3. 自定义映射。

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

   Dozer对于基本类型之间转换是不用配置的,比如Sting <------>Integer ,只要属性名称相同就Ok了。

   而常用的Date与String映射配置如下:

  <mapping date-format="MM-dd-yyyy">
     <class-a>net.blogjava.vincent.pojo.CustomerPo</class-a>
     <class-b>net.blogjava.vincent.vo.CustomerVo</class-b>
     <field>
       <a>birthday</a>
       <b>dateOfBirth</b>
     </field>
  </mapping>

   指明 CustomerPo里面的birthday对应CustomerVo里面的dateOfBirth.并且是Date与String之间双向映射。

对于属性名称不一致,也仅仅需要一个配置文件,如下:

  <mapping>
      <class-a>net.blogjava.vincent.pojo.CustomerPo</class-a>
      <class-b>net.blogjava.vincent.vo.CustomerVo</class-b>
       <field>
           <a>type</a>
            <b>transferType</b>
          </field>
 </mapping>

 

指明 CustomerPo里面的type 对应CustomerVo里面的transferType.

而对以级联,比如CustomerPo里面的一个属性映射为CustomerVo里么一个对象的属性,下面的配置就可以了

   <mapping>
      <class-a>net.blogjava.vincent.pojo.CustomerPo</class-a>
      <class-b>net.blogjava.vincent.vo.CustomerVo</class-b>
       <field>
       <a>type</a>
     <b>transferType.type</b>
   </field>
    </mapping>

   上面其实就是Dozer基本用法,也涵盖了大多数应用场景,可见基本不需要写代码,仅仅一个配置文件搞定,简单吧。

   而对以更个性化的映射,就需要写代码了, 比如在CustomerPo中的into类型的transferId ,映射CustomerVo  String 类型transferType, 如果transferId =1 对应transferType=“immediateTranfer” 如果transferId =2 对应transferType=“scheduleTransfer” 反之亦然。就要写一个Customer的Map了, 如下:

import org.dozer.CustomConverter;

public class CustomerMap implements CustomConverter {

    public Object convert(Object destinationFieldValue,
            Object sourceFieldValue, Class<?> destinationClass,
            Class<?> sourceClass) {
        Object returnVale = null;
        if(sourceFieldValue!=null){
            if(sourceFieldValue instanceof Integer ){
                if((Integer)sourceFieldValue == 1){
                    returnVale ="immediateTranfer";
                }
                if((Integer)sourceFieldValue == 2){
                    returnVale ="scheduleTransfer";
                }
               
            }
            if(sourceFieldValue instanceof String ){
                if("immediateTranfer".equals(destinationFieldValue)){
                    returnVale =1;
                }
                if("scheduleTransfer".equals(destinationFieldValue)){
                    returnVale =2;
                }
               
            }

        }
        return returnVale;
    }

}

 

 然后在配置文件配置就Ok了 如下:

      <mapping>
          <class-a>net.blogjava.vincent.pojo.CustomerPo</class-a>
         <class-b>net.blogjava.vincent.vo.CustomerVo</class-b>
       <field custom-converter="net.blogjava.vincent.mapUtil.CustomerMap">
       <a>type</a>
      <b>transferType</b>
      </field>
    </mapping>

下面就是一个完整的配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://dozer.sourceforge.net E:dozerdozer-5.0-srcdozer-5.0srcsiteresourcesschemabeanmapping.xsd"
    xmlns="http://dozer.sourceforge.net">
    <mapping  date-format="yyyy-MM-dd">
        <class-a>net.blogjava.vincent.pojo.UserInfo</class-a>
        <class-b>net.blogjava.vincent.vo.UserInfoVo</class-b>
        <field>
            <a>colleage.name</a>
            <b>schoolName</b>
        </field>
    </mapping>
        <mapping>
        <class-a>net.blogjava.vincent.pojo.CustomerPo</class-a>
        <class-b>net.blogjava.vincent.vo.CustomerVo</class-b>
         <field custom-converter="net.blogjava.vincent.mapUtil.CustomerMap">
            <a>type</a>
            <b>transferType</b>
        </field>
    </mapping>

</mappings>

 

 

3.注入配置Injecting Custom Mapping Files

Dozer同样支持IOC容器的注入(现在很难找到不支持spring容器的项目了),同样也支持代码方式的注入:


The Dozer mapping xml file(s) define any custom mappings that can't be automatically performed by the Dozer mapping engine. Any custom Dozer mapping files need to be injected into the Mapper implementation(org.dozer.DozerBeanMapper). Both setter-based and constructor-based injection are supported.
Preferably, you will be using an IOC framework such as Spring for these Dozer injection requirements. Alternatively, the injection of mapping files can be done programatically. Below is a programmatic approach to creating a bean mapper. Note that this is NOT the recommended way to retrieve the bean mapper . Each new instance needs to be initialized and this consumes time as well as resources. If you are using the mapper this way just wrap it using the singleton pattern.


先看spring方式的注入:

Xml代码 复制代码
  1. <bean id="mapper" class="org.dozer.DozerBeanMapper">  
  2.   <property name="mappingFiles">  
  3.     <list>  
  4.       <value>dozer-global-configuration.xml</value>               
  5.       <value>dozer-bean-mappings.xml</value>  
  6.       <value>more-dozer-bean-mappings.xml</value>  
  7.     </list>  
  8.   </property>  
  9. </bean>  
Xml代码 复制代码
  1. <SPAN style="COLOR: #000000; BACKGROUND-COLOR: #ffffff"><bean id="mapper" class="org.dozer.DozerBeanMapper">  
  2.   <property name="mappingFiles">  
  3.     <list>  
  4.       <value>dozer-global-configuration.xml</value>               
  5.       <value>dozer-bean-mappings.xml</value>  
  6.       <value>more-dozer-bean-mappings.xml</value>  
  7.     </list>  
  8.   </property>  
  9. </bean></SPAN>  

 

再看代码方式的注入(!!!非推荐方式)

Each new instance needs to be initialized and this consumes time as well as resources. If you are using the mapper this way just wrap it using the singleton pattern.

Java代码 复制代码
  1. List myMappingFiles = new ArrayList();   
  2. myMappingFiles.add("dozerBeanMapping.xml");   
  3. myMappingFiles.add("someOtherDozerBeanMappings.xml");   
  4. DozerBeanMapper mapper = new DozerBeanMapper();   
  5. mapper.setMappingFiles(myMappingFiles);   
  6. DestinationObject destObject = mapper.map(sourceObject, DestinationObject.class);  
Java代码 复制代码
  1. <SPAN style="COLOR: #000000; BACKGROUND-COLOR: #ffffff">List myMappingFiles = new ArrayList();   
  2. myMappingFiles.add("dozerBeanMapping.xml");   
  3. myMappingFiles.add("someOtherDozerBeanMappings.xml");   
  4. DozerBeanMapper mapper = new DozerBeanMapper();   
  5. mapper.setMappingFiles(myMappingFiles);   
  6. DestinationObject destObject = mapper.map(sourceObject, DestinationObject.class);</SPAN>  

 

springside里面实现的Dozer单例:

Java代码 复制代码
  1. package org.springside.modules.utils;   
  2.   
  3. import net.sf.dozer.util.mapping.DozerBeanMapper;   
  4. import net.sf.dozer.util.mapping.MapperIF;   
  5.   
  6. /**  
  7.  * 辅助DTO复制的Dozer工具类的单例wrapper.  
  8.  *   
  9.  * Dozer在同一JVM里使用单例即可,无需重复创建.  
  10.  * 但Dozer4自带的DozerBeanMapperSingletonWrapper必须使用dozerBeanMapping.xml作参数初始化,因此重新实现无配置文件的版本.  
  11.  *   
  12.  * @author calvin  
  13.  */  
  14. public final class DozerMapperSingleton {   
  15.   
  16.     private static MapperIF instance = new DozerBeanMapper();//使用预初始化避免并发问题.   
  17.   
  18.     private DozerMapperSingleton() {   
  19.     }   
  20.   
  21.     public static MapperIF getInstance() {   
  22.         return instance;   
  23.     }   
  24. }  

2.加载dozer组件工具:
    List mappingfilelist=new ArrayList();
    mappingfilelist.add(Constants.dozer。Xml);
    mif = new DozerBeanMapper(mappingfilelist);

    mif.map(source,destination);