簡體   English   中英

使用實體方法作為 MapStruct 源

[英]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 的一個簡單應用程序,在搜索了幾個小時后,我們對沒有提出一個干凈的解決方案感到非常失望。

解決方案

我們發現了兩種可行的解決方案,但(在我們看來)不是真正可維護的:

  1. 使用@Mapping(expression = "java(...)")
  2. 使用@AfterMapping對構造的DTO進行后期處理,並在注解的方法中實現所需的映射

問題

有沒有更簡潔的方法來實現我們的目標,可能看起來像這樣@Mapping(sourceMethod = "calculateAge", target = "age)

有沒有更清潔的方法來實現我們的目標,可能看起來像這樣......

不,截至撰寫此答案的 MapStruct 最新穩定版本( 1.4.1.Final )還沒有。 您基本上有兩個選擇,這在很大程度上取決於您想要 map 字段的確切內容和方式。 我簡要描述了每種解決方案適用於什么情況:

  1. 使用表達式的第一個解決方案引入了方法在注釋中硬編碼的問題。 我只在不調用自定義方法(僅來自現有的 Java API 的情況下)的簡單格式轉換或計算的情況下更喜歡此解決方案。 無論如何,即使使用您提出的解決方案,它仍然是硬編碼的。 語法是唯一改變的東西。 在可維護性方面實際上沒有區別:

    •  @Mapping(target = "age", expression = "java(...)") // current API
    •  @Mapping(sourceMethod = "calculateAge", target = "age") // hypothetical

    隨時請求此類功能。 在任何情況下,此解決方案還需要在映射器( @Mapper(imports = Another.class) )以及“假設的”映射器中導入。

  2. 注釋@AfterMapping在更復雜的轉換和計算的情況下很有用。 它不像單個注釋調用那樣干凈,實際上您仍然手動編寫映射,但是,它可以更好地控制 IDE 在編譯之前突出顯示的調用方法(至少您不需要額外的特定於 IDE 的插件)。 如果我需要調用我的自定義方法和邏輯,我會為此解決方案使用 go。

據我所知,Mapstruct 依賴於標准的 getter 和 setter。 如果您想使用特定方法,那么 Mapstruct 確實可以使用 @qualifiers,但我認為該方法不能在實體中。 正如您所提到的,根據我的經驗,最好的解決方案是使用@AfterMapping。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM