Java中ModelMapper?的高級使用
ModelMapper 高級使用
ModelMapper 是一個 Object To Object 的工具,類似于 MapStruct又不同于 MapStruct。主要原因是 ModelMapper 是利用反射的原理實現(xiàn)的 Object To Object。
ModelMapper 官方API : http://modelmapper.org/user-manual/property-mapping/
使用實例
本實例實現(xiàn)了條件映射、嵌套映射(對象中有對象映射)、自定義屬性映射、List 集合映射(對象中有集合映射)、Map集合映射(對象中有集合映射)、忽略映射,默認(rèn)值設(shè)置(ModelMapper 的默認(rèn)值設(shè)置時一不小心就會入坑,如果直接設(shè)置默認(rèn)值,當(dāng)再賦值轉(zhuǎn)換時,默認(rèn)值會覆蓋賦值的值,所以設(shè)置默認(rèn)值需要結(jié)合條件映射)等。
驗證了對象屬性為集合,集合中還有集合能夠使用 ModelMapper 進行轉(zhuǎn)換。不足點是這個實例中沒有驗證有繼承關(guān)系時的映射(使用 modelMapper.includeBase(父類1, 父類2) 方法),多個屬性映射為一個屬性或一個屬性映射為多個屬性(使用 PropertyMap 轉(zhuǎn)換器)。
- 使用條件映射設(shè)置默認(rèn)值。當(dāng) age/createTime 沒有值時設(shè)置默認(rèn)值為18/當(dāng)前時間,有值時不設(shè)置默認(rèn)值;
- 嵌套映射,自定義屬性映射。Source 的 sourceSon 成員變量 映射到 Destination 的 destinationSon 成員變量;
- List集合映射。Source 的 listSon 成員變量 映射到 Destination 的 sonList 成員變量;
- Map集合映射。Source 的 mapSon 成員變量 映射到 Destination 的 sonMap 成員變量;
- 忽略映射。忽略 Destination 的 excessParam 成員變量,如果不忽略將驗證不過,報 org.modelmapper.MappingException: ModelMapper mapping errors;
實體類
(1)BaseClass
@Getter @Setter public class BaseClass { ? ? private String id; ? ? private String name; ? ? public BaseClass() { ? ? } ? ? public BaseClass(String id, String name) { ? ? ? ? this.id = id; ? ? ? ? this.name = name; ? ? } }
(2)SouSubClass
@Getter @Setter public class SouSubClass { ? ? private String sonId; ? ? private String sonName; ? ? private List<BaseClass> grandSons; ? ? public SouSubClass() { ? ? } ? ? public SouSubClass(String sonId, String sonName) { ? ? ? ? this.sonId = sonId; ? ? ? ? this.sonName = sonName; ? ? } }
(3)DestSubClass
@Getter @Setter public class DestSubClass { ? ? private String dsonId; ? ? private String sonName; ? ? private String excessParam; ? ? private List<BaseClass> grandSons; ? ? public DestSubClass(){ ? ? } ? ? public DestSubClass(String dsonId, String sonName) { ? ? ? ? this.dsonId = dsonId; ? ? ? ? this.sonName = sonName; ? ? } }
(4)Source
@Getter @Setter public class Source { ? ? private String id; ? ? private String name; ? ? private Integer age; ? ? private SouSubClass sourceSon; ? ? private List<SouSubClass> listSon; ? ? private Map<Integer, SouSubClass> mapSon; ? ? private Date createTime; ? ? public Source() { ? ? } ? ? public Source(String id, String name) { ? ? ? ? this.id = id; ? ? ? ? this.name = name; ? ? } ? ? public Source(String id, String name, Integer age) { ? ? ? ? this.id = id; ? ? ? ? this.name = name; ? ? ? ? this.age = age; ? ? } }
(5)Destination
@Getter @Setter public class Destination { ? ? private Long id; ? ? private String name; ? ? private Integer age; ? ? private DestSubClass destinationSon; ? ? private List<DestSubClass> sonList; ? ? private Map<Integer, DestSubClass> sonMap; ? ? private String excessParam; ? ? private Date createTime; ? ? public Destination() { ? ? } ? ? public Destination(Long id, String name) { ? ? ? ? this.id = id; ? ? ? ? this.name = name; ? ? } }
ModelMapper 配置類
/** ?* 描述:ModelMapper 配置 ?*/ @Configuration public class ModelMapperConfig { ? ? @Bean ? ? @Scope("singleton") ? ? public ModelMapper getModelMapper() { ? ? ? ? ModelMapper modelMapper = new ModelMapper(); ? ? ? ? //默認(rèn)為standard模式,設(shè)置為strict模式 ? ? ? ? modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT); ? ? ? ? // 類型映射代碼 ? ? ? ? sourceSonToDestinationSon(modelMapper); ? ? ? ? sourceToDestination(modelMapper); ? ? ? ? //驗證映射 ? ? ? ? modelMapper.validate(); ? ? ? ? // 配置代碼 ? ? ? ? return modelMapper; ? ? } ? ? /** ? ? ?* 描述:聲明 Source 類轉(zhuǎn) Destination 類的 Mapper ? ? ?* @param modelMapper ? ? ?* @Date ?2019/05/09 ? ? ?*/ ? ? private void sourceSonToDestinationSon(ModelMapper modelMapper) { ? ? ? ? modelMapper.createTypeMap(SouSubClass.class, DestSubClass.class) ? ? ? ? ? ? ? ? .addMapping(SouSubClass::getSonId, DestSubClass::setDsonId) ? ? ? ? ? ? ? ? .addMapping(SouSubClass::getSonName, DestSubClass::setSonName) ? ? ? ? ? ? ? ? .addMappings(mapper -> mapper.skip(DestSubClass::setExcessParam)); ? ? } ? ? private void sourceToDestination(ModelMapper modelMapper) { ? ? ? ? modelMapper.createTypeMap(Source.class, Destination.class) ? ? ? ? ? ? ? ? .addMappings(mapper -> mapper.using((Converter<Integer, Integer>) context -> { ? ? ? ? ? ? ? ? ? ? ? ? if (context.getSource() == null) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? return 18; ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? return context.getSource(); ? ? ? ? ? ? ? ? ? ? }).map(Source::getAge, Destination::setAge)) ? ? ? ? ? ? ? ? .addMappings(mapper -> mapper.using((Converter<Date, Date>) context -> { ? ? ? ? ? ? ? ? ? ? ? ? if (context.getSource() == null) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? return new Date(); ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? return context.getSource(); ? ? ? ? ? ? ? ? ? ? }).map(Source::getCreateTime, Destination::setCreateTime)) ? ? ? ? ? ? ? ? .addMapping(Source::getSourceSon, Destination::setDestinationSon) ? ? ? ? ? ? ? ? .addMapping(Source::getListSon, Destination::setSonList) ? ? ? ? ? ? ? ? .addMapping(Source::getMapSon, Destination::setSonMap) ? ? ? ? ? ? ? ? .addMappings(mapper -> mapper.skip(Destination::setExcessParam)); ? ? } }
ModelMapper Service 類
public interface TestService { ? ? Destination testSourceToDestination(Source source); ? ? List<Destination> testSourceToDestinationList(List<Source> sources); }
@Service public class TestServiceImpl implements TestService { ? ? @Autowired ? ? private ModelMapper modelMapper; ? ? @Override ? ? public Destination testSourceToDestination(Source source) { ? ? ? ? Destination destination = modelMapper.map(source, Destination.class); ? ? ? ? return destination; ?// a 處 ? ? } ? ? @Override ? ? public List<Destination> testSourceToDestinationList(List<Source> sources) { ? ? ? ? Type type = new TypeToken<List<Destination>>(){}.getType(); ? ? ? ? List<Destination> destinations = modelMapper.map(sources, type); ? ? ? ? return destinations; // b 處 ? ? } }
測試類
@RunWith(SpringRunner.class) @SpringBootTest(classes = TestApplication.class) public class TestServiceImplTest { ? ? @Autowired ? ? private TestService testService; ? ? private static Source source1 = new Source("a", "發(fā)生的", 24); ? ? private static Source source2 = new Source("b", "發(fā)生的"); ? ? private static List<Source> sources = new ArrayList<>(); ? ? static { ? ? ? ? List<BaseClass> baseClasses1 = new ArrayList<>(); ? ? ? ? baseClasses1.add(new BaseClass("aa", "發(fā)生的111")); ? ? ? ? baseClasses1.add(new BaseClass("bb", "發(fā)生的222")); ? ? ? ? SouSubClass subClass1 = new SouSubClass("aaa", "發(fā)生的3333"); ? ? ? ? subClass1.setGrandSons(baseClasses1); ? ? ? ? List<BaseClass> baseClasses2 = new ArrayList<>(); ? ? ? ? baseClasses2.add(new BaseClass("cc", "國防觀")); ? ? ? ? baseClasses2.add(new BaseClass("dd", "國防觀")); ? ? ? ? SouSubClass subClass2 = new SouSubClass("ccc", "規(guī)范的大哥"); ? ? ? ? subClass2.setGrandSons(baseClasses2); ? ? ? ? List<SouSubClass> sourceSonList = new ArrayList<>(); ? ? ? ? sourceSonList.add(subClass1); ? ? ? ? sourceSonList.add(subClass2); ? ? ? ? Map<Integer, SouSubClass> sourceSonMap = new HashMap<>(); ? ? ? ? sourceSonMap.put(1, subClass1); ? ? ? ? sourceSonMap.put(2, subClass2); ? ? ? ? source1.setCreateTime(new Date(System.currentTimeMillis()-98978609)); ? ? ? ? source1.setSourceSon(subClass1); ? ? ? ? source1.setListSon(sourceSonList); ? ? ? ? source1.setMapSon(sourceSonMap); ? ? ? ? source2.setSourceSon(subClass1); ? ? ? ? source2.setListSon(sourceSonList); ? ? ? ? source2.setMapSon(sourceSonMap); ? ? ? ? sources.add(source1); ? ? ? ? sources.add(source2); ? ? } ? ? @Test ? ? public void testSourceToDestination() { ? ? ? ? testService.testSourceToDestination(source1); ? ? ? ? testService.testSourceToDestination(source2); ? ? } ? ? @Test ? ? public void testSourceToDestinationList() { ? ? ? ? testService.testSourceToDestinationList(sources); ? ? } }
測試結(jié)果
在 ab 兩處打上斷點,查看變量轉(zhuǎn)換前后的值,證實轉(zhuǎn)換成功。
到此這篇關(guān)于Java中ModelMapper 的高級使用的文章就介紹到這了,更多相關(guān)Java ModelMapper內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
javaweb 國際化:DateFormat,NumberFormat,MessageFormat,ResourceBu
本文主要介紹javaWEB國際化的知識,這里整理了詳細的資料及實現(xiàn)代碼,有興趣的小伙伴可以參考下2016-09-09SpringBoot集成ShedLock實現(xiàn)分布式定時任務(wù)流程詳解
ShedLock是一個鎖,官方解釋是他永遠只是一個鎖,并非是一個分布式任務(wù)調(diào)度器。一般shedLock被使用的場景是,你有個任務(wù),你只希望他在單個節(jié)點執(zhí)行,而不希望他并行執(zhí)行,而且這個任務(wù)是支持重復(fù)執(zhí)行的2023-02-02Spring Boot集成kubernetes客戶端實現(xiàn)API操作k8s集群的方案
Kubernetes是一個開源的容器編排平臺,可以自動化在部署、管理和擴展容器化應(yīng)用過程中涉及的許多手動操作,這篇文章主要介紹了Spring Boot集成kubernetes客戶端實現(xiàn)API操作k8s集群,需要的朋友可以參考下2024-08-08