1. 程式人生 > 其它 >PO,BO,VO和POJO的區別

PO,BO,VO和POJO的區別

PO:持久物件

  • PO:persistent object 持久物件
    1. 有時也被稱為Data物件,對應資料庫中的entity,可以簡單認為一個PO對應資料庫中的一條記錄。
    2. 在hibernate持久化框架中與insert/delet操作密切相關。
    3. PO中不應該包含任何對資料庫的操作。
    4. 它跟持久層(通常是關係型資料庫)的資料結構形成一一對應的對映關係,如果持久層是關係型資料庫,那麼,資料表中的每個欄位(或若干個)就對應PO的一個(或若干個)屬性。

POJO:無規則簡單java物件

  • POJO:plain ordinary java object 無規則簡單java物件、PO和VO都屬於它。
  • 是一箇中間物件,可以轉化為PO、DTO、VO。
    1. POJO持久化之後==〉PO
      -(在執行期,由Hibernate中的cglib動態把POJO轉換為PO,PO相對於POJO會增加一些用來管理資料庫entity狀態的屬性和方法。PO對於programmer來說完全透明,由於是執行期生成PO,所以可以支援增量編譯,增量除錯。)
    2. POJO傳輸過程中==〉DTO
    3. POJO用作表示層==〉VO

BO:business object 業務物件

  • 業務物件主要作用是把業務邏輯封裝為一個物件。這個物件可以包括一個或多個其它的物件,用來封裝PO
  • 比如一個簡歷,有教育經歷、工作經歷、社會關係等等。我們可以把教育經歷對應一個PO,工作經歷對應一個PO,社會關係對應一個PO。
  • 建立一個對應簡歷的BO物件處理簡歷,每個BO包含這些PO。
  • 這樣處理業務邏輯時,我們就可以針對BO去處理。
  • 封裝業務邏輯為一個物件(可以包括多個PO,通常需要將BO轉化成PO,才能進行資料的持久化,反之,從DB中得到的PO,需要轉化成BO才能在業務層使用)。
  • 關於BO主要有三種概念
    1. 只包含業務物件的屬性;
    2. 只包含業務方法;
    3. 兩者都包含。
  • 在實際使用中,認為哪一種概念正確並不重要,關鍵是實際應用中適合自己專案的需要。

VO:value object 值物件 / view object 表現層物件

  1. 主要對應頁面顯示(web頁面/swt、swing介面)的資料物件。用於表現層,它的作用是把某個指定頁面(或元件)的所有資料封裝起來。
  2. 可以和表對應,也可以不,這根據業務的需要。

DTO(TO):Data Transfer Object 資料傳輸物件

  1. 用在需要跨程序或遠端傳輸時,它不應該包含業務邏輯。泛指用於展示層與服務層之間的資料傳輸物件。
  2. 比如一張表有100個欄位,那麼對應的PO就有100個屬性(大多數情況下,DTO內的資料來自多個表)。但view層只需顯示10個欄位,沒有必要把整個PO物件傳遞到client
    ,這時我們就可以用只有這10個屬性的DTO來傳輸資料到client,這樣也不會暴露server端表結構。到達客戶端以後,如果用這個物件來對應介面顯示,那此時它的身份就轉為VO。

DAO:data access object資料訪問物件

  1. 主要用來封裝對DB的訪問(CRUD操作)。
  2. 通過接收Business層的資料,把POJO持久化為PO。

DO(Domain Object):

  • 領域物件,就是從現實世界中抽象出來的有形或無形的業務實體。

簡易的關係圖

VO與DTO的區別

  • 大家可能會有個疑問:既然DTO是展示層與服務層之間傳遞資料的物件,為什麼還需要一個VO呢?對!對於絕大部分的應用場景來說,DTO和VO的屬性值基本是一致的,而且他們通常都是POJO,因此沒必要多此一舉,但不要忘記這是實現層面的思維,對於設計層面來說,概念上還是應該存在VO和DTO,因為兩者有著本質的區別,DTO代表服務層需要接收的資料和返回的資料,而VO代表展示層需要顯示的資料。
  • 用一個例子來說明可能會比較容易理解:例如服務層有一個getUser的方法返回一個系統使用者,其中有一個屬性是gender(性別),對於服務層來說,它只從語義上定義:1-男性,2-女性,0-未指定,而對於展示層來說,它可能需要用“帥哥”代表男性,用“美女”代表女性,用“祕密”代表未指定。說到這裡,可能你還會反駁,在服務層直接就返回“帥哥美女”不就行了嗎?對於大部分應用來說,這不是問題,但設想一下,如果需求允許客戶可以定製風格,而不同風格對於“性別”的表現方式不一樣,又或者這個服務同時供多個客戶端使用(不同門戶),而不同的客戶端對於表現層的要求有所不同,那麼,問題就來了。再者,回到設計層面上分析,從職責單一原則來看,服務層只負責業務,與具體的表現形式無關,因此,它返回的DTO,不應該出現與表現形式的耦合。

DTO與DO的區別

  • 首先是概念上的區別,DTO是展示層和服務層之間的資料傳輸物件(可以認為是兩者之間的協議),而DO是對現實世界各種業務角色的抽象。
  • 兩者在資料上的區別就是DTO可以省略一些DO不需要返回給前端的欄位。
  • 例如UserInfo和User,對於一個getUser方法來說,本質上它永遠不應該返回使用者的密碼,因此UserInfo至少比User少一個password的資料。而在領域驅動設計中,DO不是簡單的POJO,它具有領域業務邏輯。

DO與PO的區別

  • DO和PO在絕大部分情況下是一一對應的,PO是隻含有get/set方法的POJO,但某些場景還是能反映出兩者在概念上存在本質的區別:
  • DO在某些場景下不需要進行顯式的持久化,例如利用策略模式設計的商品折扣策略,會衍生出折扣策略的介面和不同折扣策略實現類,這些折扣策略實現類可以算是DO,但它們只駐留在靜態記憶體,不需要持久化到持久層,因此,這類DO是不存在對應的PO的。
  • 同樣的道理,某些場景下,PO也沒有對應的DO,例如老師Teacher和學生Student存在多對多的關係,在關係資料庫中,這種關係需要表現為一箇中間表,也就對應有一個TeacherAndStudentPO的PO,但這個PO在業務領域沒有任何現實的意義,它完全不能與任何DO對應上。這裡要特別宣告,並不是所有多對多關係都沒有業務含義,這跟具體業務場景有關,例如:兩個PO之間的關係會影響具體業務,並且這種關係存在多種型別,那麼這種多對多關係也應該表現為一個DO,又如:“角色”與“資源”之間存在多對多關係,而這種關係很明顯會表現為一個DO——“許可權”。
  • 某些情況下,為了某種持久化策略或者效能的考慮,一個PO可能對應多個DO,反之亦然。例如客戶Customer有其聯絡資訊Contacts,這裡是兩個一對一關係的DO,但可能出於效能的考慮(極端情況,權作舉例),為了減少資料庫的連線查詢操作,把Customer和Contacts兩個DO資料合併到一張資料表中。反過來,如果一本圖書Book,有一個屬性是封面cover,但該屬性是一副圖片的二進位制資料,而某些查詢操作不希望把cover一併載入,從而減輕磁碟IO開銷,同時假設ORM框架不支援屬性級別的延遲載入,那麼就需要考慮把cover獨立到一張資料表中去,這樣就形成一個DO對應對個PO的情況。
  • PO的某些屬性值對於DO沒有任何意義,這些屬性值可能是為了解決某些持久化策略而存在的資料,例如為了實現“樂觀鎖”,PO存在一個version的屬性,這個version對於DO來說是沒有任何業務意義的,它不應該在DO中存在。同理,DO中也可能存在不需要持久化的屬性。

entity和domain包名區別

  • (1)、entity(實體)
    • entity的意思就是實體的意思,所以也是最常用到的,entity包中的類是必須和資料庫相對應的,比如說:資料庫有個user表,欄位有long型別的id,string型別的姓名,那麼entity中的user類也必須是含有這兩個欄位的,且型別必須一致。不能資料庫存的是long型別,user類裡的屬性是string型別。這樣做的好處是保持實體類和資料庫保持一致,另外,當用到hibernate或是mybatie框架來操作資料庫的時候,操作這個實體類就行,寫sql文之前不需要再做資料格式處理。
  • (2)、model(模型)
    • model大家不陌生,都知道是模型的意思,當用model當包名的時候,一般裡面存的是實體類的模型,一般是用來給前端用的。比如:前端頁面需要顯示一個user資訊,user包含姓名,性別,居住地,這些資訊存在資料庫的時候,姓名直接存姓名,但是性別和居住地一般會用資料字典的編號存到資料庫,比如:111代表男,222代表女,資料庫存的就是111或222,如果用entity的話,把111、222前端都不知道是什麼玩意,就算前端知道111代表男,222代表女,寫了一個js判斷資料處理。後來資料庫變動了,111代表女,222代表男,前端的js又需要重新寫,很顯然這樣不利於維護。所以就需要model來解決,後臺從資料庫取了資料轉化為前端需要的資料直接傳給前端,前端就不需要對資料來處理,直接顯示就行了。還有一種情況,資料庫裡面的user表字段有十個,包含姓名,qq,生辰八字亂七八糟的等,但是前臺頁面只需要顯示姓名,如果把entity全部傳給前臺,無疑傳了很多沒用的資料。這時候model就很好的解決了這個問題,前臺需要什麼資料,model就包含什麼資料就行了

(3)、domain(域) (DO)

  • domain這個包國外很多專案經常用到,字面意思是域的意思。範圍有點廣了,比如一個商城的專案,商城主要的模組就是使用者,訂單,商品三大模組,那麼這三塊資料就可以叫做三個域,domain包裡就是存的就是這些資料,表面上這個包和entity和model包裡存的資料沒什麼區別,其實差別還是挺大的,特別是一些大型的專案。比如一個招聘網站的專案,最重要的物件就是簡歷了,那麼簡歷是怎麼存到資料庫的呢,不可能用一張表就能存的,因為簡歷包含基本資訊和工作經驗,專案經驗,學習經驗等。基本資訊可以存在簡歷表,但是涉及到多條的就不行,因為沒人知道有多少條工作經驗,專案經驗,所以必須要單獨建工作經驗表和專案經驗表關聯到簡歷基本資訊表。但是前臺頁面是不關心這些的,前臺需要的資料就是一個簡歷所有資訊,這時就可以用到domain來處理,domain裡面的類就是一個簡歷物件,包含了簡歷基本資訊以及list的工作經驗,專案經驗等。這樣前端只需要獲取一個物件就行了,不需要同時即要獲取基本資訊,還要從基本資訊裡面獲取工作經驗關聯的簡歷編號,然後再去獲取對應的工作經驗了。

三句話總結下entity、model、domain的不同

  1. entity欄位:必須和資料庫欄位一樣
  2. model欄位:前端需要什麼我們就給什麼
  3. domain很少用,代表一個物件模組

實體entity、JavaBean、Model、POJO、domain的區別

  • Java Bean、POJO、Entity、VO ,其實都是java 物件,只不過用於不同場合罷了。
  • 按照 Spring MVC 分層結構:
    • JavaBean: 表示層 (Presentation Layer)
    • Entity: 業務層 (Service layer)
    • Dao資料訪問層 (data access layer)。
  • Entity接近原始資料,Model接近業務物件~
  • Entity:是專用於EF的對資料庫表的操作
  • Model:是為頁面提供資料和資料校驗的,所以兩者可以並存
  • POJO:POJO是Plain OrdinaryJava Object的縮寫不錯,但是它通指沒有使用Entity Beans的普通- - java物件,可以把POJO作為支援業務邏輯的協助類。
  • domain:domain這個包國外很多專案經常用到,字面意思是域的意思。
  • POJO實質上可以理解為簡單的實體類,顧名思義POJO類的作用是方便 程式設計師使用資料庫中的資料表,對於廣大的程式設計師,可以很方便的將POJO類當做物件來進行使用,當然也是可以方便的呼叫其get,set方法。
  • JavaBean: 先說JavaBean,JavaBean更多的是一種規範,也即包含一組set和get方法的Java物件。
  • POJO: 普通的Java物件,對於屬性一般實現了JavaBean的標準,另外還可以包含一些簡單的業務邏輯(方法)。
  • **PO: **POJO在持久層的體現,對POJO持久化後就成了PO。PO更多的是跟資料庫設計層面相關,一般PO與資料表對應,一個PO就是對應資料表的一條記錄。
  • **DAO: **PO持久化到資料庫是要進行相關的資料庫操作的(CRUQ),這些對資料庫操作的方法會統一放到一個Java物件中,這就是DAO。
  • **BO: **POJO在業務層的體現,對於業務操作來說,更多的是從業務上來包裝物件,如一個User的BO,可能包括name, age, sex, privilege, group等,這些屬性在資料庫中可能會在多張表中,因為每一張表對應一個PO,而我們的BO需要這些PO組合起來(或說重新拼裝)才能成為業務上的一個完整物件。
  • VO(Value Object/View Object): POJO在表現層的體現。 當我們處理完資料時,需要展現時,這時傳遞到表現層的POJO就成了VO。它就是為了展現資料時用的。
  • **DTO(Data Transfer Object): **POJO在系統間傳遞時。當我們需要在兩個系統間傳遞資料時,一種方式就是將POJO序列化後傳遞,這個傳遞狀態的POJO就是DTO。
  • EJB(Enterprise JavaBean): 我認為它是一組”功能”JavaBean的集合。上面說了JavaBean是實現了一種規範的Java物件。這裡說EJB是一組JavaBean,的意思是這一組JavaBean組合起來實現了某個企業組的業務邏輯。這裡的一組JavaBean不是亂組合的,它們要滿足能實現某項業務功能的搭配。找個比方,對於一身穿著來說,包括一頂帽子,一件衣服,一條褲子,兩隻鞋,這穿著就是EJB.