PO即 Persistence Object
VO即 Value Object

VO和PO的主要区别在于:
  VO是独立的Java Object。
  PO是由Hibernate纳入其实体容器(Entity Map)的对象,它代表了与数据库中某条记录对应的Hibernate实体,PO的变化在事务提交时  将 反应到实际数据库中。

 实际上,这个VO被用作Data Transfer Object,即所谓的DTO。想必,VO就是Data Access Object ---DAO了啦。为什么要有这二者之分呢?如在传统的MVC架构中,位于Model层的PO,是否允许被传递到其他层面。由于PO的更新最终将被映射到实际数据库中,如果PO在其他层面(如View层)发生了变动,那么可能会对Model层造成意想不到的破坏。

 主要想说的还是如何进行二者之间的转换:
  属性复制可以通过Apache Jakarta Commons Beanutils(http://jakarta.apache.org/commons/beanutils/)组件提供的属性批量复制功能,避免繁复的get/set操作。down下来之后,里面的API DOC一应俱全。

 对于一些无需处理其它处理(如过滤)直接用BeanUtilsBean.copyProperties方法,其参考如下:

public   static   void  copyProperties(java.lang.Object dest,  java.lang.Object orig)         throws           java.lang.IllegalAccessException,
 
// java.lang.reflect.InvocationTargetExceptioCopy property values from the origin bean to the destination bean for all cases where the property names are the same.


 
  范例1:

TUser user  =   new  TUser();
TUser anotherUser 
=   new  TUser();
user.setName(
" Emma " );
user.setUserType(
1 );
try   {
BeanUtils.copyProperties(anotherUser,user);
System.out.println(
" UserName =>  "
+ anotherUser.getName()
);
System.out.println(
" UserType =>  "
+  anotherUser.getUserType()
);
}
  catch  (IllegalAccessException e)  {
e.printStackTrace();
}
  catch  (InvocationTargetException e)  {
e.printStackTrace();
}
 



 也可以利用其中的一些方法在copy属性的时候达到自己的要求,如:

 范例2

/** //*
 * Created on 2006-4-26
 
*/

package  com.util;

import  java.beans.PropertyDescriptor;
import  java.util.Collection;

import  org.apache.commons.beanutils.PropertyUtils;


/**   */ /**
 * CopyUtil
 * 
@author  Jkallen
 
*/

public   class  CopyUtil  {
    
    
/**   */ /**
     * Copy properties of orig to dest
     * Exception the Entity and Collection Type
     * 
@param  dest
     * 
@param  orig
     * 
@return  the dest bean
     
*/

    
public   static  Object copyProperties(Object dest, Object orig)  {
        
if  (dest  ==   null   ||  orig  ==   null {
            
return  dest;
        }

        
        PropertyDescriptor[] destDesc 
=  PropertyUtils.getPropertyDescriptors(dest);
        
try   {
            
for  ( int  i  =   0 ; i  <  destDesc.length; i ++ {
                Class destType 
=  destDesc[i].getPropertyType();
                Class origType 
=  PropertyUtils.getPropertyType(orig, destDesc[i].getName());
                
if (destType  !=   null   &&  destType.equals(origType)
                        
&&   ! destType.equals(Class. class ))  {
                    
if ( ! Collection. class .isAssignableFrom(origType)) {                    
                        
try {
                            Object value 
=  PropertyUtils.getProperty(orig, destDesc[i].getName());
                            PropertyUtils.setProperty(dest, destDesc[i].getName(), value);
                        }
catch (Exception ex) {                            
                        }

                    }

                }

            }

            
            
return  dest;
        }
catch (Exception ex)  {
            
throw   new  CopyException(ex);
//             return dest;
        }

    }
    
    
    
/**   */ /**
     * Copy properties of orig to dest
     * Exception the Entity and Collection Type
     * 
@param  dest
     * 
@param  orig
     * 
@param  ignores
     * 
@return  the dest bean
     
*/

    
public   static  Object copyProperties(Object dest, Object orig, String[] ignores)  {
        
if  (dest  ==   null   ||  orig  ==   null {
            
return  dest;
        }

        
        PropertyDescriptor[] destDesc 
=  PropertyUtils.getPropertyDescriptors(dest);
        
try   {
            
for  ( int  i  =   0 ; i  <  destDesc.length; i ++ {
                
if  (contains(ignores, destDesc[i].getName()))  {
                    
continue ;
                }

                
                Class destType 
=  destDesc[i].getPropertyType();
                Class origType 
=  PropertyUtils.getPropertyType(orig, destDesc[i].getName());
                
if (destType  !=   null   &&  destType.equals(origType)
                        
&&   ! destType.equals(Class. class ))  {
                    
if ( ! Collection. class .isAssignableFrom(origType)) {
                        Object value 
=  PropertyUtils.getProperty(orig, destDesc[i].getName());
                        PropertyUtils.setProperty(dest, destDesc[i].getName(), value);
                    }

                }

            }

            
            
return  dest;
        }
catch (Exception ex)  {
            
throw   new  CopyException(ex);
        }

    }

    
    
static   boolean  contains(String[] ignores, String name)  {
        
boolean  ignored  =   false ;
        
for  ( int  j  =   0 ; ignores  !=   null   &&  j  <  ignores.length; j ++ {
            
if  (ignores[j].equals(name))  {
                ignored 
=   true ;
                
break ;
            }

        }

        
        
return  ignored;
    }

}


  

  可以看到,在范例1中通过方法copyProperties的时候,二者之间在的属性名必须相同(Copy property values from the origin bean to the destination bean for all cases where the property names are the same)。而在范例2中通过
   Object value = PropertyUtils.getProperty(orig, destDesc[i].getName());
    PropertyUtils.setProperty(dest, destDesc[i].getName(), value);
  也是将源与目的之间copy相同的属性名。而VO是在前台显示,所以难免会用到PO中所不存在的属性值。比如PO中可能是一个对象,而VO中则可能是此对象的全部属性。其中的一些转换则需要依据前台需 要针对性地处理啦!
         在copy的过程中,若实体中存在一对多,多对多等关系,则DTO中也应该存在此关系,此时不能直接将内部的DTO or List(一对多)里面的数据一次性全部拷过去,这时应该对每个DTO进行copy,当然,若在前台你无需用到相关的DTO则可以跳过。而对于一对多(LIST),而应将实体里面的每个一对多转换成对应的DTO,再依次放到LSIT里面,再将此LIST赋值给(父)DTO,这里面的关系如同(一个简单的)递归关系。---