Spring REST API应用中Entity与DTO互转最佳方案及转换器优化咨询
Spring REST Entity与DTO转换优化方案
你当前的抽象转换器思路是合理的,只需要优化抽象层的通用逻辑,就可以省去每个子类都写模板转换方法的重复工作。
1 改造抽象父类,实现通用转换逻辑
由于Java泛型运行时会擦除,我们可以在父类新增构造方法,要求子类传入泛型对应的Class对象,父层即可直接实现通用的单对象转换逻辑,无需每个子类重复实现:
public abstract class AbstractConverter<Entity, DTO> { @Autowired protected ModelMapper modelMapper; private final Class<Entity> entityClass; private final Class<DTO> dtoClass; // 构造方法,子类初始化时传入对应泛型的Class对象 protected AbstractConverter(Class<Entity> entityClass, Class<DTO> dtoClass) { this.entityClass = entityClass; this.dtoClass = dtoClass; } // 通用单对象转Entity,子类有自定义转换逻辑可重写 public Entity toEntity(DTO dto) { return dto == null ? null : modelMapper.map(dto, entityClass); } // 通用单对象转DTO,子类有自定义转换逻辑可重写 public DTO toDTO(Entity entity) { return entity == null ? null : modelMapper.map(entity, dtoClass); } public List<Entity> toEntityList (Iterable<DTO> listDTO) { List<Entity> list = new ArrayList<>(); if(listDTO != null) { for (DTO dto:listDTO) { list.add(toEntity(dto)); } } return list; } public List<DTO> toDTOList (Iterable<Entity> listEntity) { List<DTO> list = new ArrayList<>(); if(listEntity != null) { for (Entity entity:listEntity) { list.add(toDTO(entity)); } } return list; } }
2 简化子类实现
改造后无特殊转换逻辑的业务转换器,仅需要调用父类构造方法传入对应Class即可,无需重复写转换方法:
@Component public class UserConverter extends AbstractConverter<User, UserDTO> { // 无特殊逻辑不需要重写转换方法 public UserConverter() { super(User.class, UserDTO.class); } // 遇到特殊转换场景时再重写父类方法即可,示例: // @Override // public UserDTO toDTO(User user) { // UserDTO dto = super.toDTO(user); // dto.setFullName(user.getFirstName() + user.getLastName()); // return dto; // } }
3 额外优化建议
- ModelMapper全局配置优化:在配置类中声明单例ModelMapper,开启严格匹配策略,避免字段不匹配时的隐式转换错误,也可以统一配置跨类型转换器,比如Date和LocalDateTime的互转:
@Bean public ModelMapper modelMapper() { ModelMapper mm = new ModelMapper(); mm.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT); return mm; } - 批量转换方法简化:用Stream API替换循环逻辑,代码更简洁:
public List<DTO> toDTOList (Iterable<Entity> listEntity) { return listEntity == null ? Collections.emptyList() : StreamSupport.stream(listEntity.spliterator(), false) .map(this::toDTO) .filter(Objects::nonNull) .collect(Collectors.toList()); } - 高性能方案替换:如果对转换性能要求较高,可以替换为MapStruct框架,它会在编译期自动生成类型安全的转换实现,不需要反射调用,运行效率和手写代码一致,也不需要手动编写基础转换逻辑。
内容的提问来源于stack exchange,提问作者Luca De Salve
相关产品推荐
相关产品推荐

