Entity與DTO區別及其使用

爲何不能直接用實體模型實現層與層傳遞?

DTO(Data Tansfer Object)即數據傳輸對象。不明白有些框架中爲何要專門定義DTO來綁定表現層中的數據,爲何不能直接用實體模型實現層與層之間的數據傳輸,有了DTO同時還要維護DTO與Model之間的映射關係與轉換?前端

表現層與應用層之間是經過數據傳輸對象(DTO)進行交互的,數據傳輸對象是沒有行爲的POJO對象,它 的目的只是爲了對領域對象進行數據封裝,實現層與層之間的數據傳遞。爲什麼不能直接將領域對象用於 數據傳遞?由於領域對象更注重領域,而DTO更注重數據。不只如此,因爲「富領域模型」的特色,這樣作會直接將領域對象的行爲暴露給表現層。java

須要瞭解的是,數據傳輸對象DTO自己並非業務對象。數據傳輸對象是根據UI的需求進行設計的,而不 是根據領域對象進行設計的。好比,Customer領域對象可能會包含一些諸如FirstName, LastName, Email, Address等信息。但若是UI上不打算顯示Address的信息,那麼CustomerDTO中也無需包含這個Address的數據。web

簡單來講Model面向業務,咱們是經過業務來定義Model的。而DTO是面向界面UI,是經過UI的需求來定義的。經過DTO咱們實現了表現層與Model之間的解耦,表現層不引用Model,若是開發過程當中咱們的模型改變了,而界面沒變,咱們就只須要改Model而不須要去改表現層中的東西。sql

爲何要用DTO

這裏是列表文本session

  • JavaEE各層之間解耦,這是從設計角度來講的。也就是說Domain Object(PO)直接封死在Dao層。高內聚,低耦合是咱們追求的一個目標。但因爲在通常的應用中大量的PO,VO轉換,增長了工做量,也有些人說是過分設計。
  • 這裏是列表文本隔離變化。當在一些大型的應用場景以及Domain常常變化的系統裏,View層能夠只關注DTO對象,不用關心Domain層PO對象,如hibernate entity的不斷變化。
  • 這裏是列表文本利於發揮我的技術特長,特別是按層來分工開發的團隊。若有人專一於Web層,只作SpringMVC和界面這部分。還有人專門作Spring和Hibernate部分。兩組的開發人員定義好接口數據就行,也就是DTO(VO)。咱們當時作的電子商務網站就是這樣的。
  • 這裏是列表文本當系統發展大後,擴展成各類前端界面後,能夠有效隔離核心應用層。如又有web界面,又有swing的cs界面,又有手機客戶端。
  • 這裏是列表文本當分層部署時,也就是Web層(jsp,Struts2)和App層(Spring,dao)在不一樣機器上時,用Remote協議通迅,DTO是必需的。如處理hibernate lazy load和序列化等問題。在電子商務應用中分層部署的主要好處是減小各層負載量,提升性能。
  • 這裏是列表文本在一些特定場景,如須要防火牆的地方,須要把核心數據層(Service,Dao,DB)放在防火牆內。

JPA的OTD使用方式

假設有一個DTO,其屬性包括兩張表的屬性,須要將sql語句查詢獲得的內容轉爲一個DTO對象,其解決方法以下:框架

方法一:

SQLQuery query = session.createSQLQuery("select a.id as areaId,a.name as areaName,c.id as screenId,c.name as screenName from HPS_ParkingLotArea a left join HPS_ParkingLotScreen c on a.screenId = c.id ");
List list = query
.addScalar("areaId",Hibernate.INTEGER)
.addScalar("areaName",Hibernate.STRING)
.addScalar("screenId",Hibernate.INTEGER)
.addScalar("screenName",Hibernate.STRING)
.setResultTransformer(Transformers.aliasToBean(AreaWithScreen.class)).list();
return list;

在執行完sql語句以後,取到相應的屬性,並賦予其類型,最後藉助aliasToBean來轉化爲相應的類的實例。(此類無需有其餘構造方法)jsp

方法二:

Query q = session.createQuery("select new com.hibernate.MsgInfo(m.id, m.cont, m.topic.title, m.topic.category.name) from Msg m");  
List<MsgInfo> list=q.list();

其中,MsgInfo是DTO。值得留意的是,第二種方法中DTO必須提供帶參數的構造方法,而且HQL語句中屬性的位置要與構造方法中的位置逐一對應。性能

對於DTO對象要注意,是int仍是Integer。若是是int,但set方法中的方法也是int,則若是爲空,會報錯。網站

參考博客

DTO與實體對象的區別:http://blog.csdn.net/wzhjdls/article/details/26938909.net

生成DTO的兩種方式:http://blog.csdn.net/angus_17/article/details/8500103

相關文章
相關標籤/搜索