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