JAVA

人生若只如初见,何事秋风悲画扇。

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  50 随笔 :: 25 文章 :: 157 评论 :: 0 Trackbacks

 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,这里面的关系如同(一个简单的)递归关系。---更新于5-25-2006

Reference:  Apache DOC and <<Hibernate 开发指南>>               

posted on 2006-04-26 14:55 Jkallen 阅读(6671) 评论(8)  编辑  收藏 所属分类: JEE学习其它开源

评论

# re: VO(DTO)与PO(DAO)之间的转换 2006-04-26 17:48 寒晴天
我想问你你代码的样式怎么弄的啊.好看,真好看.  回复  更多评论
  

# re: VO(DTO)与PO(DAO)之间的转换 2006-04-26 17:48 寒晴天
说话,说话.  回复  更多评论
  

# re: VO(DTO)与PO(DAO)之间的转换 2006-04-26 17:50 寒晴天
看的不是太明白哦  回复  更多评论
  

# re: VO(DTO)与PO(DAO)之间的转换 2006-04-27 08:51 蓝天
我倒!
这个兄弟怎么不抓住重点呢?
  回复  更多评论
  

# re: VO(DTO)与PO(DAO)之间的转换 2006-04-27 08:54 蓝天
编辑的时候注意下,也有的.  回复  更多评论
  

# re: VO(DTO)与PO(DAO)之间的转换 2006-04-29 12:53 dennis
试试dozer吧,更为强大  回复  更多评论
  

# re: VO(DTO)与PO(DAO)之间的转换[未登录] 2007-05-08 01:09 jerry
首先谢谢你,我还想问你要点一对多的代码可以吗/
yangjiehuan@163.com  回复  更多评论
  

# re: VO(DTO)与PO(DAO)之间的转换 2007-05-10 19:24 蓝天
一年前用DTO,DAO来配合JSP显示数据,
现在看来,这是不可取的: 增加了很多的代码量 & 增加了系统中的文件 & 日后维护麻烦(地方太多,显得过于杂乱)

solve: 在spring中通过bind可以捆定相关的对象. 结合hibernate 可以很好解决以上遇到的问题

  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: