Mapping 带自定义转换器的推土机深度特性映射

Mapping 带自定义转换器的推土机深度特性映射,mapping,dozer,Mapping,Dozer,我的应用程序中有深度属性映射(从域对象到DTO,反之亦然),类似于下一个示例: ... <field> <a>employee.id</a> <b>employeeId</a> </field> ... 在我的很多地图中 public class ManyToOneIdMapper implements ConfigurableCustomConverter{ //... //parameter fi

我的应用程序中有深度属性映射(从域对象到DTO,反之亦然),类似于下一个示例:

...

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

...
在我的很多地图中

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;
}
公共类ManyToOneIdMapper实现可配置的CustomConverter{
//...
//参数字段声明、setParameter和getParameter实现等。
//...
公共对象转换(对象existingDestinationFieldValue、对象sourceFieldValue、,
类destinationClass、类sourceClass){
试一试{
if(sourceClass.equals(Integer.class)){
整数src=(整数)sourceFieldValue;
如果(src==null | | src==0)
返回null;
字符串setterName=formatMethodName(“set”,getParameter());
方法setterMethod=destinationClass.getMethod(setterName,Integer.class);
对象实例=destinationClass.newInstance();
调用(实例,src);
返回实例;
}否则{
如果(sourceFieldValue==null)
返回0;
字符串getterName=formatMethodName(“get”,getParameter());
方法getterMethod=sourceClass.getMethod(getterName);
对象实例=getterMethod.invoke(sourceFieldValue);
返回实例;
}
}捕获(例外e){}
返回null;
}
/**
*@return-根据fieldName的方法名(通常是setter或getter)。
*例如formatMethodName(“get”,“id”)返回“getId”
*/
受保护的字符串formatMethodName(字符串方法前缀,字符串字段名){
String trimmedFieldName=fieldName.trim();
String firstLetter=String.valueOf(trimmedFieldName.charAt(0));
字符串大写的dfirstletter=firstLetter.toUpperCase();
字符串methodName=methodPrefix+“”+capitalizedFirstLetter+“”+fieldName.substring(1);
返回方法名;
}

custom converter param
只是域对象中id字段的名称。使用该名称,我只需调用转换器中的setter或getter方法。可能这不是最令人满意的解决方案,但它适用于我的问题场景。

您想要一个
CustomConverter
来映射父对象,例如:

领域

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


您希望使用
CustomConverter
映射两个类
PersonA
PersonB
,这将允许您以任何方式构建它们。

您可以使用
CustomConverter
(根据另一个答案),或使用
DozerEventListener
在映射完成后将employee对象设置回null(如果ID为0)。

您可以签出(作者在此处)。它将智能地映射您描述的场景,而不需要任何配置或自定义转换器。考虑到模型:

class Person {
  Employee employee;
}

class Employee {
  int id;
}

class PersonDTO {
  int employeeId;
}
映射很简单:

ModelMapper modelMapper = new ModelMapper();
PersonDTO personDTO = modelMapper.map(person, PersonDTO.class);
若要在
PersonDTO.employeeId
不为零时有条件地映射
Person.employee
,我们只需创建一个条件并使用该条件为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=新条件(){
应用公共布尔值(映射上下文){
返回context.getSource().getEmployeeId()!=0;
}
};
addMappings(新属性映射(){
受保护的void configure(){
when(empIdIsNotZero).map(source).setEmployee(null);
}
});
empIdIsNotZero
条件适用时,映射将正常进行。否则,映射将被跳过,
Person.employee
将设置为null

有关更多文档和示例,请访问ModelMapper网站:


对于DTO->Domain案例,您是否希望使用已保存在数据库中的ID查找员工?@Terrell Plotzki-不完全是。如果DTO.employeeId为0或更低,我只想将Domain.employeeId设置为null。我更改了我的问题。您必须在回答中披露您与该产品的联系。示例b我很感激。
ModelMapper modelMapper = new ModelMapper();
PersonDTO personDTO = modelMapper.map(person, PersonDTO.class);
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);
  }
});