modelmapperを触ってみた
modelmapperは、開発でよく出くわす「〜層へのオブジェクト伝搬。(Bean Mapping)」これをさくっと出来るライブラリらしいです。最近infoqで取り上げられていました。「en」「jp」
例えば、T1#name1をT2#name1に値コピーとT2のBean生成.
class T1 { private String name1; //getter setter name1; } class T2 { private String name1; private String name2; private String name3 = "hello"; //getter setter name1,name2; } main(String... args) { T1 t1 = new T1(); t1.setName1("hello"); ModelMapper mapper = new ModelMapper(); T2 t2 = mapper.map(t1,T2.class); System.out.println(t2.getName1()); } //console:>hello
次に、T1#name1をT2#name2に値コピーとT2のBean生成.
main(String... args) { T1 t1 = new T1(); t1.setName1("hello2"); PropertyMap<T1,T2> pmap = new PropertyMap<T1, T2>() { @Override protected void configure() { map().setName2(source.getName1()); } }; ModelMapper mapper = new ModelMapper(); mapper.addMappings(pmap); T2 t2 = mapper.map(t1,T2.class); System.out.println(t2.getName2()); } //console:>hello2
次に、T1#name1をT2#name3に値コピー(上書き)とT2のBean生成.
ただし、T1#name1がnullの場合、値は上書きしない。
main(String... args) { T1 t1 = new T1(); t1.setName1("hello3"); PropertyMap<T1,T2> pmap = new PropertyMap<T1, T2>() { @Override protected void configure() { when(new Condition<T1,T2>() { @Override public boolean applies(MappingContext<T1, T2> context) { return context.getSource() != null; } }).map().setName3(source.getName1()); } }; ModelMapper mapper = new ModelMapper(); mapper.addMappings(pmap); T2 t2 = mapper.map(t1,T2.class); System.out.println(t2.getName3()); t1.setName1(null); t2 = mapper.map(t1,T2.class); System.out.println(t2.getName3()); } //console:>hello3 //console:>hello
その他、値のconverter等が出来るらしい。(まだ1時間程度しか触っていないため、機能の詳細はつかめず)
こういったBean Mappingライブラリは、単純なものだとBean Utils等で済ませられるが、単純すぎて使えないシーンが多い。また、Dozer等はXMLが面倒で私の気性にあわなくてだめ。また、文字列でBean同士のMappingをするライブラリ(ognl?)もIDEの支援が受けられなくて、Propertieの名称が変わると面倒。
というわけで、「modelmapper」はBean Mapping の操作はごりごりとgetter/setterでやっていた派としては割と好感触。ただ、安定性はいまいちつかめない。少なくとも、propertiesのスキップ条件とマッピング条件の整理と、Conditional Mappingを使わないで定義できる条件のバリエーションをそろえた方が使い勝手はよいと思う。とりあえず、この3連休forkして見てみようと。