ModelMapper实现DTO转Entity:如何无条件保留未映射字段原值
解决ModelMapper更新实体时保留原有字段值的问题
要实现DTO映射到现有实体时,只更新DTO携带的字段、保留实体其他原有值,且无需耦合具体字段名或getter/setter,按以下步骤操作:
1. 修正映射调用方式
不要用modelMapper.map(dto, Deliver.class)创建新实体,而是直接将DTO映射到从数据库查询到的现有实体对象上:
// 从数据库获取待更新的实体 Deliver existingDeliver = deliverRepository.findById(deliverId).orElseThrow(() -> new RuntimeException("Deliver not found")); // 将DTO字段映射到现有实体,而非生成新实例 modelMapper.map(dto, existingDeliver); // 保存更新后的实体 deliverRepository.save(existingDeliver);
2. 全局配置ModelMapper
创建Spring配置类,配置ModelMapper的核心规则,实现自动保留未映射字段值、减少耦合:
import org.modelmapper.ModelMapper; import org.modelmapper.config.Configuration.AccessLevel; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class ModelMapperConfig { @Bean public ModelMapper modelMapper() { ModelMapper modelMapper = new ModelMapper(); // 允许直接访问私有字段,无需依赖getter/setter,降低耦合 modelMapper.getConfiguration() .setFieldAccessLevel(AccessLevel.PRIVATE) .setFieldMatchingEnabled(true) // 跳过DTO中值为null的字段,避免覆盖实体原有非null值 .setSkipNullEnabled(true); return modelMapper; } }
关键配置说明
setSkipNullEnabled(true):映射时忽略DTO中值为null的字段,仅更新DTO中有有效值的字段,实体原有字段保持不变。setFieldMatchingEnabled(true)+setFieldAccessLevel(AccessLevel.PRIVATE):直接通过字段名匹配映射,不需要依赖getter/setter的命名规则,彻底解除和方法名的耦合。- 即使DTO中存在某个字段但值为null,该配置也不会覆盖实体对应字段的原有值;如果DTO中不存在某个字段,ModelMapper不会对实体的该字段做任何修改,自然保留原有值。
内容的提问来源于stack exchange,提问作者Giovanni
相关产品推荐
相关产品推荐

