2011-06-16 58 views
2

我在我的應用程序(從域對象DTO,和反向),類似於下面的例子深物業映射:與自定義轉換器推土機深屬性格式映射

... 

<field> 
    <a>employee.id</a> 
    <b>employeeId</a> 
</field> 

... 

當推土機轉換域名到DTO,它將employee.id映射到employeeId,那沒關係。
當Dozer將DTO轉換爲域時,它將employeeId映射到id = employeeId的新Employee實例。

我想創建一些邏輯,爲這個深屬性映射,但我只是不能找出解決方案。我試圖執行CustomConverter(或擴展DozerConverter),但Dozer將Integer類型作爲源類和目標類傳遞給我(並期望Integer作爲結果)。

編輯: 更確切地說,我需要的是在域圖employeenull如果employeeId在DTO是0

這可能嗎?

有什麼建議嗎?

根據答案編輯: 我解決了現場級自定義轉換器的問題。取代先前的,上面提到的,測繪,現在我有這樣的事情...

... 

<field custom-converter="ManyToOneIdMapper" custom-converter-param="id"> 
    <a>employee</a> 
    <b>employeeId</b> 
</field> 

... 

在ManyToOneIdMapper我有...

public class ManyToOneIdMapper implements ConfigurableCustomConverter{ 

//... 
//parameter field declaration, setParameter and getParameter implementations etc. 
//... 

public Object convert(Object existingDestinationFieldValue, Object sourceFieldValue, 
     Class<?> destinationClass, Class<?> sourceClass) { 
    try { 

     if(sourceClass.equals(Integer.class)){ 
      Integer src=(Integer)sourceFieldValue; 

      if(src==null || src==0) 
       return null; 

      String setterName=formatMethodName("set", getParameter()); 
      Method setterMethod=destinationClass.getMethod(setterName, Integer.class); 
      Object instance=destinationClass.newInstance(); 

      setterMethod.invoke(instance, src); 

      return instance; 
     }else{  
      if(sourceFieldValue==null) 
       return 0; 

      String getterName=formatMethodName("get", getParameter()); 
      Method getterMethod=sourceClass.getMethod(getterName); 
      Object instance=getterMethod.invoke(sourceFieldValue); 

      return instance; 
     } 
    } catch (Exception e){} 
    return null; 
} 

/** 
* @return - method name (most often setter or getter) according to fieldName. 
* For example formatMethodName("get", "id") returns "getId" 
*/ 
protected String formatMethodName(String methodPrefix, String fieldName){ 
    String trimmedFieldName=fieldName.trim(); 
    String firstLetter=String.valueOf(trimmedFieldName.charAt(0)); 
    String capitalizedFirstLetter=firstLetter.toUpperCase(); 
    String methodName=methodPrefix+""+capitalizedFirstLetter+""+fieldName.substring(1); 

    return methodName; 
} 

custom-converter-param在Domain對象僅僅是名稱ID場。用這個名字,我只是在我的轉換器中調用setter或getter方法。可能它不是最快樂的解決方案,但它適用於我的問題場景。

+0

對於DTO->域的情況下,你想與ID這已經是持續在數據庫中執行員工的查找? – 2011-06-16 03:13:41

+0

@Terrell Plotzki - 不完全。如果DTO.employeeId爲0或更少,我只想將Domain.employee設置爲null。我改變了我的問題。 – slomir 2011-06-16 09:40:17

回答

0

你想要一個CustomConverter映射的父對象,例如:

class PersonA { 
    ... 
    int employeeId; 
    ... 
} 

DTO

class PersonB { 
    ... 
    Employee employee; 
    ... 
} 

class Employee { 
    ... 
    int id; 
    ... 
} 

你想使用CustomConverter兩類PersonAPersonB地圖,這會讓你構建他們想要的任何方式。

1

您可以使用CustomConverter(根據對方的回答)一個,或使用DozerEventListener設置員工對象回空映射完成後,如果ID爲0

0

你可以看看ModelMapper (作者在這裏)。它將智能地映射您描述的場景,而不需要任何配置或自定義轉換器。考慮到模型:

class Person { 
    Employee employee; 
} 

class Employee { 
    int id; 
} 

class PersonDTO { 
    int employeeId; 
} 

映射很簡單:

ModelMapper modelMapper = new ModelMapper(); 
PersonDTO personDTO = modelMapper.map(person, PersonDTO.class); 

有條件地映射Person.employeePersonDTO.employeeId不爲零,我們只是創造條件,並添加屬性映射Person.employee與條件:

Condition<?, ?> empIdIsNotZero = new Condition<PersonDTO, Employee>() { 
    public boolean applies(MappingContext<PersonDTO, Employee> context) { 
    return context.getSource().getEmployeeId() != 0; 
    } 
}; 

modelMapper.addMappings(new PropertyMap<PersonDTO, Person>() { 
    protected void configure() { 
    when(empIdIsNotZero).map(source).setEmployee(null); 
    } 
}); 

empIdIsNotZero條件適用時,映射將正常進行。否則映射將被跳過並且Person.employee將被設置爲空。

退房的ModelMapper網站更多的文檔和示例:

http://modelmapper.org

+0

您必須在答案中公佈您與產品的關係。 – Brandon 2014-11-19 15:46:13

+0

沒問題 - 完成 – Jonathan 2014-11-19 18:45:23