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