1. 程式人生 > >java開發中DTO、VO、PO之間的轉換你應該這麼操作

java開發中DTO、VO、PO之間的轉換你應該這麼操作

痛點

一種框架的出現都要解決個痛點,我想下面這這種不方便的操作經常有人寫吧。

假如Car 類是資料庫對映類

CarDTO是DTO 類

通常我們會這麼寫一個方法進行轉換

甚至中間還牽涉了很多型別轉換,巢狀之類的繁瑣操作,而我們想要的只是建立它們之間的對映關係而已。有沒有一種通用的對映工具來幫我們搞定這一切。當然有而且還不少。有人說apache的BeanUtil.copyProperties 可以實現,但是效能差而且容易出異常,很多規範嚴禁使用這種途徑。以下是對幾種物件對映框架的對比,大多數情況下 MapStruct 效能最高。類似於lombok ,Mapstruct都是在編譯期進行實現,所以一般不存在執行時效能問題。

so,今天就搞一搞MapStruct, 無論是idea 還是eclipse 都建議安裝 mapstruct 外掛。

安裝

引入maven 依賴座標

編寫對映

我們把開始的痛點解決一下,編寫Car到CarDTO的對映。

宣告一個對映介面用@org.mapstruct.Mapper 標記,說明這是一個bean轉換介面。這裡我們聲明瞭一個 CAR_MAPPING 來方便我們呼叫,CarDTO toCarDTO(Car car)是不是很熟悉, 像mybatis一樣抽象出我們的轉換方法。org.mapstruct.Mapping註解用來宣告成員屬性的對映。這裡以成員變數的引數名為依據,如果有巢狀比如Car裡面有個CarType型別的成員變數type,其type屬性 來對映CarDTO中的type字串,我們使用type.type 來獲取屬性值。如果有多層以此類推。mapStruct 最終呼叫的是setter和getter 方法,而非反射。這也是其效能比較好的原因之一。numberOfSeats 對映到seatCount 就比較好理解了。我們是不是忘記了一個屬性make,因為他們的位置且名稱完全一致,所以可以省略。而且對於包裝類是自動拆箱封箱操作的,並且是執行緒安全的。MapStruct不單單有這些功能,還有其他一些複雜的功能:

  • 設定轉換預設值和常量。當目標值是null 我們可以設定其預設值,注意這些都是基本型別以及對應都boxing型別,如下

@Mapping(target = "stringProperty", source = "stringProp", defaultValue = "undefined")

需要注意的是常量不能對源進行引用(不能指定source屬性),下面是正確的操作

@Mapping(target = "stringConstant", constant = "Constant Value")

  • 格式化也是我們經常使用的操作,比如數字格式化,日期格式化。

這是處理數字格式化的操作,遵循java.text.DecimalFormat的規範

@Mapping(source = "price", numberFormat = "$#.00")

下面展示了將一個日期集合對映到日期字串集合的格式化操作上,遵循的

@IterableMapping(dateFormat = "dd.MM.yyyy") List<String> stringListToDateList(List<Date> dates);

  • 我們還經常使用spring component 來處理 我們只需要這麼宣告,不用再構建一個單例,就可以像其他 spring bean一樣對CarMapping 進行引用了。

總結

其實MapStruct 還有很多的功能。但是從可讀性來說,我建議使用以上幾種容易理解的功能即可。如果你感興趣可以去mapstruct.org進一步學習。配合lombok和我介紹的jsr303,讓你更加專注於業務,而且程式碼更加清晰。

多多關注我的微信公眾號:碼農小胖哥 ,分享更多技