<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
ModelMapper 是一個 Object To Object 的工具,類似於 MapStruct又不同於 MapStruct。主要原因是 ModelMapper 是利用反射的原理實現的 Object To Object。
ModelMapper 官方API : http://modelmapper.org/user-manual/property-mapping/
本範例實現了條件對映、巢狀對映(物件中有物件對映)、自定義屬性對映、List 集合對映(物件中有集合對映)、Map集合對映(物件中有集合對映)、忽略對映,預設值設定(ModelMapper 的預設值設定時一不小心就會入坑,如果直接設定預設值,當再賦值轉換時,預設值會覆蓋賦值的值,所以設定預設值需要結合條件對映)等。
驗證了物件屬性為集合,集合中還有集合能夠使用 ModelMapper 進行轉換。不足點是這個範例中沒有驗證有繼承關係時的對映(使用 modelMapper.includeBase(父類別1, 父類別2) 方法),多個屬性對映為一個屬性或一個屬性對映為多個屬性(使用 PropertyMap 轉換器)。
(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 設定 */ @Configuration public class ModelMapperConfig { @Bean @Scope("singleton") public ModelMapper getModelMapper() { ModelMapper modelMapper = new ModelMapper(); //預設為standard模式,設定為strict模式 modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT); // 型別對映程式碼 sourceSonToDestinationSon(modelMapper); sourceToDestination(modelMapper); //驗證對映 modelMapper.validate(); // 設定程式碼 return modelMapper; } /** * 描述:宣告 Source 類轉 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)); } }
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", "發生的", 24); private static Source source2 = new Source("b", "發生的"); private static List<Source> sources = new ArrayList<>(); static { List<BaseClass> baseClasses1 = new ArrayList<>(); baseClasses1.add(new BaseClass("aa", "發生的111")); baseClasses1.add(new BaseClass("bb", "發生的222")); SouSubClass subClass1 = new SouSubClass("aaa", "發生的3333"); subClass1.setGrandSons(baseClasses1); List<BaseClass> baseClasses2 = new ArrayList<>(); baseClasses2.add(new BaseClass("cc", "國防觀")); baseClasses2.add(new BaseClass("dd", "國防觀")); SouSubClass subClass2 = new SouSubClass("ccc", "規範的大哥"); 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); } }
在 ab 兩處打上斷點,檢視變數轉換前後的值,證實轉換成功。
到此這篇關於Java中ModelMapper 的高階使用的文章就介紹到這了,更多相關Java ModelMapper內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45