dozer与BeanUtils

    xiaoxiao2024-05-27  102

    呵呵,在《develope J2EE without EJB》中,DTO被狠很地批判了一把,rod说这完全是反模式。可实际项目当中,我们还是不得不在使用。VO,PO,一牵扯到概念总是多么复杂。。。把一个PO从头传到尾??从页面到数据库,一捅到底?NO,NO,万一你要显示给用户的是几个PO的结合怎么办?万一我们只是需要某几个属性组合在一起显示怎么办?一捅到底的策略是多么丑陋,而且你完全把你的数据库设计模型暴露给用户。所以我们需要一些map工具来转换,在这方面,过去我只知道有个 BeanUtils,不够灵活,而今天,接触了下dozer,啊,跟spring一样的理念!灵活多变,你想怎么映射,想怎么换都可以。看看它支持的转换类型:

    • Primitive to Primitive Wrapper • Primitive to Custom Wrapper • Primitive Wrapper to Primitive Wrapper

    • Primitive to Primitive • Complex Type to Complex Type • String to Primitive • String to Primitive Wrapper • String to Complex Type if the Complex Type contains a String constructor • Each of these can be mapped to one another: java.util.Date, java.sql.Date, java.sql.Time, java.sql.Timestamp, java.util.Calendar, java.util.GregorianCalendar • String to any of the supported Date/Calendar Objects if an explicit date format mapping attribute is specified. • Objects containing a toString() method that produces a long representing time in (ms) to any supported Date/Calendar object.

    几乎我们能想到的,它都提供了方法来做到。而且dozer可以很容易地跟spring集成。下面举个简单例子:

    定义一个Book对象:

    package com.denny_blue.dozerdemo; public class Book {  private String name;  private String author;      public Book(){     }   public void setAuthor(String author) {   this.author = author;  }

     public String getAuthor() {   return (this.author);  }  public void setName(String name){   this.name=name;  }   public String getName(){   return this.name;  } } 简单的,我们要实例化一个对象,然后clone此对象,注意,是clone!

    package com.denny_blue.dozerdemo; import net.sf.dozer.util.mapping.DozerBeanMapper; import java.util.List; import java.util.ArrayList;

    public class MyFirstDozerDemo {  public static void main(String args[]){   Book book1=new Book();   book1.setAuthor("dennis");   book1.setName("dozer demo");   DozerBeanMapper mapper=new DozerBeanMapper();   Book book2=new Book();   mapper.map(book1,book2);   book2=(Book)mapper.map(book1,com.denny_blue.dozerdemo.Book.class);   System.out.println("book2's name:"+book2.getName());      } } 

    OK,如此简单,我们把book1的属性完全复制给了book2,两者现在是完全独立的对象。可如果仅仅是这样,我们用BeanUtils不是也很容易办到? book2=(Book)BeanUtils.cloneBean(book1);可如果我要把book1映射给一个完全不同的类的对象怎么办?而且他们的属性名也不相同,怎么办?比如,一个CookBook类:

    package com.denny_blue.dozerdemo; public class CookBook {  private String bookName;  private String author;

     public CookBook(){}  public String getBookName() {   return (this.bookName);  }

     public void setBookName(String bookName) {   this.bookName = bookName;  }

     public String getAuthor() {   return (this.author);  }

     public void setAuthor(String author) {   this.author = author;  }

    } 它的bookName属性与Book的name属性名不一样,我们该如何复制?dozer通过xml文件的配置来灵活地达到这个目的。我们配置一个dozerBeanMapping.xml:

    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mappings PUBLIC "-//DOZER//DTD MAPPINGS//EN" "http://dozer.sourceforge.net/dtd/dozerbeanmapping.dtd"> <mappings> <configuration> <stop-on-errors>false</stop-on-errors> <date-format>MM/dd/yyyy HH:mm</date-format> <wildcard>true</wildcard> </configuration> <mapping> <class-a>com.denny_blue.dozerdemo.Book</class-a> <class-b>com.denny_blue.dozerdemo.CookBook</class-b> <field> <a>name</a> <b>bookName</b> </field> <field> <a>author</a> <b>author</b> </field> </mapping> </mappings>

    如上所示,<class-a>指定所要复制的源对象,<class-b>复制的目标对象,<a>源对象的属性名, <b>目标对象的属性名。wildcard默认为true,在此时默认对所有属性进行map,如果为false,则只对在xml文件中配置的属性进行map。此时的demo 看起来像这样:

    package com.denny_blue.dozerdemo; import net.sf.dozer.util.mapping.DozerBeanMapper; import java.util.List; import java.util.ArrayList;

    public class MyFirstDozerDemo {  public static void main(String args[]){   Book book1=new Book();   book1.setAuthor("dennis");   book1.setName("dozer demo");   DozerBeanMapper mapper=new DozerBeanMapper();   book2=(Book)mapper.map(book1,com.denny_blue.dozerdemo.Book.class);   CookBook cookBook=new CookBook();   List myMappingFiles = new ArrayList();   myMappingFiles.add("dozerBeanMapping.xml");   mapper.setMappingFiles(myMappingFiles);   cookBook=(CookBook)mapper.map(book1,CookBook.class);   System.out.println("cookBook's name:"+   cookBook.getBookName()+"     cookBook's author:"+                       cookBook.getAuthor());  } }

    通过mapper.setMappingFiles()设置映射文件,可以添加多个配置文件,也可以把所有的映射写在一个配置文件里面。  更多复杂例子请见它自带的doc

    文章转自庄周梦蝶  ,原文发布时间5.17

    相关资源:dozer-5.3.2-src.zip
    最新回复(0)