2012-01-12 44 views
3

考慮6個POJO類:3個DAO和3個DTO。使用ModelMapper級聯PropertyMaps

的DAO: 「A」, 「B」, 「C」
DTO的: 「一」, 「二」, 「三」

public class A { 

    private int idOfA; 
    private String name; 
    private List<B> b; 

    // getters, setters, etc... 
} 

public class B { 

    private int idOfB; 
    private String name; 
    private List<C> c; 

    // getters, setters, etc... 
} 

public class C { 

    private int idOfC; 
    private String name; 

    // getters, setters, etc... 
} 



public class One { 

    private int id; 
    private String name; 
    private List<Two> two; 

    // getters, setters, etc... 
} 

public class Two { 

    private int id; 
    private String name; 
    private List<Three> Three; 

    // getters, setters, etc... 
} 

public class Three { 

    private int id; 
    private String name; 

    // getters, setters, etc... 
} 

「A」 包含的 「B」 的List 。 「B」包含「C」列表。
「One」包含「Two」列表。 「Two」包含「Three」列表。

「A」通過「A2One」映射到「One」。 「B」通過「B2Two」映射到「Two」。 「C」通過「C2Three」映射到三。

public class A2One extends PropertyMap<A, One> { 

    @Override 
    protected void configure() { 
     map().setId(source.getIdOfA()); 
     map().setName(source.getName()); 

     when(Conditions.isNotNull()).using(new BListConverter()).map(source.getBs()).setTwos(null); 
    } 
} 

public class BListConverter extends AbstractConverter<List<B>, List<Two>> { 

     @Override 
     protected List<Two> convert(List<B> source) { 

      List<Two> twos = new ArrayList<Two>(source.size()); 

      for(B b : source) { 
       Two t = new Two(); 
       t.setId(b.getId()); 
       t.setName(b.getName()); 

       // Ignore list of Cs contained in B for now 

       twos.add(t); 
      } 

      return twos; 
     } 
} 

public class B2Two extends PropertyMap<B, Two> { 

    @Override 
    protected void configure() { 
     map().setId(source.getIdOfB()); 
     map().setName(source.getName()); 

     when(Conditions.isNotNull()).using(new CListConverter()).map(source.getCs()).setThrees(null); 
    } 
} 

B2Two和C2Three的代碼與A2One非常相似。

因此,這裏是我的問題:

目前包含在「A」和列表之間的轉換「一」是通過自定義轉換器(和它的作品)做,但我重複同樣的操作, B2Two應該執行(地圖Bs到Twos)。

有沒有什麼方法級聯屬性映射(A2One - > B2Two - > C2Three)當List被映射而無需編寫一個僅僅複製屬性映射所做的轉換器?

替代1:泛型List, List創建自定義的TypeMap其轉發到正確屬性/類型地圖。

備選2:在A2One使用的列表

mapper.addMappings(new BList2TwoList()); 
when(Conditions.isNotNull()).withProvider(listProvider).map().setTwos(mapper.map(source.getBs(), List.class)); 

凡ListProvider延伸AbstractProvider返回新的ArrayList以下()

替代方案3:???

任何想法?更多涉及的映射問題的文檔在網站上很差,我不一定在尋找其他框架。如果提供替代方案,則必須允許輕鬆進行重構(因此推土機和Orika基本上都不可用)。

在此先感謝

更新: 作爲寫作的時間ModelMapper是basically dead而實際上並不支持列表或映射的級聯,這樣你將被迫寫一張地圖和一個轉換器每個對象也可以是一個列表。
此外,我發現Orika通過擴展MapperBase具有重構友好映射。此外,Orika可以透明地處理單個bean和bean列表的映射(對於兩種情況都使用單個映射規則)。

更新2: 在Orika中,可以使用CustomMapper對集合進行雙向深層嵌套映射。這樣可以創建雙向映射實現,並允許將它們級聯到其他自定義映射器。 A2One將持有一個B2Two的實例,並在映射「A」中包含的「B」時透明地使用它。

+0

感謝您正確的漂亮印花編輯德羅巴:) – xelamitchell 2012-01-12 14:40:30

+1

ModelMapper實際上是活得很好 - 0.4.0版本剛剛發佈。我一直致力於改善圖書館,如果您不介意發佈,請隨時查看您的奧裏卡解決方案。 – Jonathan 2012-07-25 23:03:50

+0

謝謝你的回覆喬納森。 基本上我的情況是,儘管ModelMapper提供了一個非常耐用的界面(通過不使用字符串來映射屬性),但它不能以透明的方式進行雙向映射(因爲PropertyMap的泛型實際上是Source和Destination而不是兩個POJO彼此映射)。 我的另一個問題是,對於封裝在對象內的深嵌套集合,使用PropertyMap變得有些尷尬,因爲我無法級聯內部項目的映射器(如上面問題中指定的那樣)。 – xelamitchell 2012-11-20 09:49:03

回答

1

使用Orika我能夠以簡單友好的方式獲得所需的所有要求。

1

我想我只是表明這是現在與模型映射器可能...

它支持列表(至少在0.7.5版本)。

的屬性映射做到這一點應該是這樣的:

public class A2One extends PropertyMap<A, One> { 

    @Override 
    protected void configure() { 
     map().setId(source.getIdOfA()); 
     map().setName(source.getName()); 

     map(source.getB()).setOne(null); 
    } 
}