[英]ModelMapper map value from Map
我正在嘗試了解以下用例的 ModelMapper:
class A {
public String name;
public Map<String, ATranslation> translations;
}
class ATranslation {
public String desc;
}
class DTO {
public String name;
public String desc;
}
假設構造函數、Getter 和 Setter。
public class App {
public static void main(String[] args) {
Map<String, ATranslation> translations = new HashMap<>();
translations.put("en", new ATranslation("en-desc"));
translations.put("nl", new ATranslation("nl-desc"));
A entity = new A("John Wick",translations);
System.out.println(App.toDto(entity,"en"));
System.out.println(App.toDto(entity,"nl"));
}
private static DTO toDto(A entity, String lang) {
ModelMapper modelMapper = new ModelMapper();
//how to set up ModelMapper?
return modelMapper.map(entity, DTO.class);
}
}
沒有任何設置 output 是:
DTO(name=John Wick, desc=null)
DTO(name=John Wick, desc=null)
轉換器不起作用:
modelMapper
.createTypeMap(A.class, DTO.class)
.setConverter(new Converter<A, DTO>() {
public DTO convert(MappingContext<A, DTO> context) {
A s = context.getSource();
DTO d = context.getDestination();
d.setDesc(s.getTranslation().get(lang).getDesc());
return d;
}
});
postConverter 確實有效,但似乎不是最 ModelMapper 的方式......
modelMapper
.createTypeMap(A.class, DTO.class)
.setPostConverter(new Converter<A, DTO>() {
public DTO convert(MappingContext<A, DTO> context) {
A s = context.getSource();
DTO d = context.getDestination();
d.setDesc(s.getTranslation().get(lang).getDesc()); //tedious, if many fields...
return d;
}
});
DTO(name=John Wick, desc=en-desc)
DTO(name=John Wick, desc=nl-desc)
有沒有更好的方法在這里使用 ModelMapper?
沒有測試它。 這只是一個由研究組成的理論答案。
由於您對 Post-Converter 的繁瑣實現的擔憂,以下解決方案是由小型組件設計的。
我嘗試將您的映射用例分解為更小的問題,並使用映射框架中的組件解決每個問題。
查看 bean 或對象或模型映射器通常是如何工作的,可能會對手頭的問題有所了解。
映射器將類型或源類 A 的 object 映射到另一個類型或目標類 B 的新 object。
我嘗試重用 Baeldung 教程中的示例:使用 ModelMapper 的指南。 我們需要3個步驟:
(a) 推斷String name
到等效目標的屬性或類型映射
(b) 表達式映射:將Map translation
為String desc
的自定義屬性映射
(c) 參數化轉換器,通過鍵String language
進行翻譯和查找,提取值ATranslation
或將其轉換為String desc
我們使用的功能是:
它以簡單的形式推斷屬性的映射。 它通過將源的屬性映射到目標來實現。 默認情況下,大多數映射器 map 的屬性與按類型或名稱等效的屬性:
字段類型和名稱完美匹配
在您的情況下,這適用於屬性String name
。
// GIVEN
Map<String, ATranslation> translations = Map.of(
"en", new ATranslation("en-desc"),
"nl", new ATranslation("nl-desc")
);
A entity = new A("John Wick", translations);
// SETUP (a) property-mapping by type
TypeMap<A, DTO> typeMap = modelMapper.createTypeMap(A.class, DTO.class);
// WHEN mapping the properties
DTO dto = modelMapper.map(entity, DTO.class);
// THEN desc expected to be null
assertNull(dto.getDesc());
assertEquals(entity.getName(), dto.getName());
在某些用例中,您需要某種類型的轉換,當無法通過簡單等價推斷出 map 的屬性類型或名稱時。
定義一個翻譯工廠方法來配置轉換器。 它會創建一個新的轉換器,或者可以根據需要說“指定語言的解釋器”。
// Converter: translates for specified language, means lookup in the map using a passed parameter
Converter<Map<String, ATranslation>, String> translateToLanguage(final String language) {
return c -> c.getOrDefault(language, new ATranslation("")).getDesc(); // language needs to be final inside a lambda
}
此方法可用於翻譯或轉換
// SETUP (a) property-mapping as default type-map
TypeMap<A, DTO> typeMap = modelMapper.createTypeMap(A.class, DTO.class);
// (b) map the property translations (even so other type) to desc
typeMap.addMapping(Source::getTranslation, Destination::setDesc);
// (c) add the converter to the property-mapper
typeMap.addMappings(
mapper -> mapper.using(translateToLanguage("nl")).map(A::getTranslation, DTO::setDesc)
);
// WHEN mapping the properties
DTO dto = modelMapper.map(entity, DTO.class);
// THEN desc expected to be mapped to the specified language's translation
assertEquals(entity.getTranslation().get("nl").getDesc(), dto.getDesc());
assertEquals(entity.getName(), dto.getName());
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.