[英]Use entity method as MapStruct source
我們目前正在使用六邊形架構實現應用程序。 我們的 REST API DTO 通過 MapStruct 映射到我們的實體。 這工作正常。 (不過,如果 MapStruct 支持分層結構會更好。)
但是,我們面臨的問題可以通過以下示例進行最佳描述:
假設您有一個存儲出生日期的實體Person
。 現在,這個實體有一個可以稱為int calculateAge()
的方法。 REST API 的PersonDto
將獲得一個屬性int age
。
現在,我們希望 MapStruct 為我們生成這個映射。 我們的方法是嘗試配置@Mapping(target = "age", ...)
以使用int calculateAge()
方法作為源,但我們沒有成功。 相信這可能是 MapStruct 的一個簡單應用程序,在搜索了幾個小時后,我們對沒有提出一個干凈的解決方案感到非常失望。
我們發現了兩種可行的解決方案,但(在我們看來)不是真正可維護的:
@Mapping(expression = "java(...)")
@AfterMapping
對構造的DTO進行后期處理,並在注解的方法中實現所需的映射有沒有更簡潔的方法來實現我們的目標,可能看起來像這樣@Mapping(sourceMethod = "calculateAge", target = "age)
?
有沒有更清潔的方法來實現我們的目標,可能看起來像這樣......
不,截至撰寫此答案的 MapStruct 最新穩定版本( 1.4.1.Final
)還沒有。 您基本上有兩個選擇,這在很大程度上取決於您想要 map 字段的確切內容和方式。 我簡要描述了每種解決方案適用於什么情況:
使用表達式的第一個解決方案引入了方法在注釋中硬編碼的問題。 我只在不調用自定義方法(僅來自現有的 Java API 的情況下)的簡單格式轉換或計算的情況下更喜歡此解決方案。 無論如何,即使使用您提出的解決方案,它仍然是硬編碼的。 語法是唯一改變的東西。 在可維護性方面實際上沒有區別:
@Mapping(target = "age", expression = "java(...)") // current API
@Mapping(sourceMethod = "calculateAge", target = "age") // hypothetical
隨時請求此類功能。 在任何情況下,此解決方案還需要在映射器( @Mapper(imports = Another.class)
)以及“假設的”映射器中導入。
注釋@AfterMapping
在更復雜的轉換和計算的情況下很有用。 它不像單個注釋調用那樣干凈,實際上您仍然手動編寫映射,但是,它可以更好地控制 IDE 在編譯之前突出顯示的調用方法(至少您不需要額外的特定於 IDE 的插件)。 如果我需要調用我的自定義方法和邏輯,我會為此解決方案使用 go。
據我所知,Mapstruct 依賴於標准的 getter 和 setter。 如果您想使用特定方法,那么 Mapstruct 確實可以使用 @qualifiers,但我認為該方法不能在實體中。 正如您所提到的,根據我的經驗,最好的解決方案是使用@AfterMapping。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.