DO與PO的區別

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中也可能存在不需要持久化的屬性。

DO與PO的應用
       由於ORM框架的功能非常強大而大行其道,而且JavaEE也推出了JPA規範,現在的業務應用開發,基本上不需要區分DO與PO,PO完全可以通過JPA,Hibernate Annotations/hbm隱藏在DO之中。雖然如此,但有些問題我們還必須注意:
對於DO中不需要持久化的屬性,需要通過ORM顯式的聲明,如:在JPA中,可以利用@Transient聲明。
對於PO中爲了某種持久化策略而存在的屬性,例如version,由於DO、PO合併了,必須在DO中聲明,但由於這個屬性對DO是沒有任何業務意義的,需要讓該屬性對外隱藏起來,最常見的做法是把該屬性的get/set方法私有化,甚至不提供get/set方法,但對於Hibernate來說,這需要特別注意,由於Hibernate從數據庫讀取數據轉換爲DO時,是利用反射機制先調用DO的空參數構造函數構造DO實例,然後再利用JavaBean的規範反射出set方法來爲每個屬性設值,如果不顯式聲明set方法,或把set方法設置爲private,都會導致Hibernate無法初始化DO,從而出現運行時異常,可行的做法是把屬性的set方法設置爲protected。
對於一個DO對應多個PO,或者一個PO對應多個DO的場景,以及屬性級別的延遲加載,Hibernate都提供了很好的支持,請參考Hibnate的相關資料。
————————————————
版權聲明:本文爲CSDN博主「zjrbiancheng」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/zjrbiancheng/article/details/6253232

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章