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,這里面的關系如同(一個簡單的)遞歸關系。---