Dozer单源对象多目标映射及字段复用可行性咨询
嘿,作为用了挺久Dozer的老玩家,来给你梳理下你的问题~
一、Dozer中实现「单源字段映射到多目标不同字段」完全可行!
不管是用XML配置还是注解(Dozer 6.x+支持注解),都能轻松实现这个需求,分两种场景给你举例:
1. 分别定义多个映射规则
假设你有两个目标类:Contractor(需要把Employee.eId映射到cId)和Manager(需要把Employee.eId映射到empId,同时把Employee.managerName映射到fullName)。
方式一:XML配置(Dozer传统且灵活的方式)
你可以在Dozer的映射文件里分别为每个目标类定义映射规则:
<mappings xmlns="http://dozer.sourceforge.net" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://dozer.sourceforge.net http://dozer.sourceforge.net/schema/beanmapping.xsd"> <!-- Employee → Contractor 的映射 --> <mapping> <class-a>com.yourpackage.Employee</class-a> <class-b>com.yourpackage.Contractor</class-b> <field> <a>eId</a> <b>cId</b> </field> <!-- 其他字段映射... --> </mapping> <!-- Employee → Manager 的映射 --> <mapping> <class-a>com.yourpackage.Employee</class-a> <class-b>com.yourpackage.Manager</class-b> <field> <a>eId</a> <b>empId</b> </field> <field> <a>managerName</a> <b>fullName</b> </field> <!-- 其他字段映射... --> </mapping> </mappings>
使用的时候,只需要根据你要转换的目标类型调用Dozer的map方法就行:
DozerBeanMapper mapper = new DozerBeanMapper(); // 转成Contractor Contractor contractor = mapper.map(employee, Contractor.class); // 转成Manager Manager manager = mapper.map(employee, Manager.class);
方式二:注解方式(Dozer 6.0+支持)
如果偏好注解驱动,你可以在目标类上添加@Mapping注解(注意是org.dozer.Mapping):
比如在Contractor类上:
public class Contractor { @Mapping("eId") // 映射Employee的eId到当前字段cId private Integer cId; // 其他字段... }
在Manager类上:
public class Manager { @Mapping("eId") // 映射Employee的eId到当前字段empId private Integer empId; @Mapping("managerName") private String fullName; // 其他字段... }
这样同样可以实现同一个eId字段映射到不同目标类的不同字段。
2. 条件式转换为不同目标对象
你的需求里提到「根据条件将源对象转换为多个目标对象」,比如根据Employee的某个属性(比如employeeType)来决定转成Contractor还是Manager,这时候只需要在业务代码里加个判断逻辑就行:
public Object convertEmployee(Employee employee) { DozerBeanMapper mapper = new DozerBeanMapper(); if ("CONTRACTOR".equals(employee.getEmployeeType())) { return mapper.map(employee, Contractor.class); } else if ("MANAGER".equals(employee.getEmployeeType())) { return mapper.map(employee, Manager.class); } // 其他情况... return null; }
如果需要更复杂的条件映射,也可以通过Dozer的自定义转换器(CustomConverter)来实现,比如在转换时根据字段值动态调整映射规则。
二、如果觉得Dozer不够顺手,这些工具也能满足需求
如果Dozer的配置方式对你来说有点繁琐,还有几个更轻量或更灵活的对象映射工具可以选:
- MapStruct:编译时生成映射代码,性能极高,注解驱动,支持条件映射、字段复用映射非常方便,比如可以直接在接口里定义多个转换方法,每个方法对应不同的目标类和字段映射规则。
- ModelMapper:无需过多配置,通过自动匹配字段名实现映射,也支持自定义映射规则,灵活性很高。
- Orika:基于字节码生成的映射工具,性能不错,支持复杂的映射场景。
这些工具都能轻松实现「单源字段映射到多目标不同字段」的需求,其中MapStruct因为是编译时生成代码,性能和可读性都很优秀,很适合复杂的映射场景。
内容的提问来源于stack exchange,提问作者Extreme

