You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用ModelMapper处理同属性名不同类型的实体与DTO互转?

用ModelMapper搞定Entity与DTO双向转换(同名属性类型不同场景)

这种同名但属性类型不匹配的映射场景我熟得很,用ModelMapper的**自定义类型转换器(Converter)**就能完美解决,比你现在写的手动转换清爽多了!下面一步步给你实现:

1. 先引入ModelMapper依赖

如果是Maven项目,在pom.xml里加这个依赖(用最新稳定版就行):

<dependency>
    <groupId>org.modelmapper</groupId>
    <artifactId>modelmapper</artifactId>
    <version>3.2.0</version>
</dependency>

2. 针对差异属性写自定义转换器

咱们要处理两个属性的双向转换:category(int ↔ String)和color(String ↔ int),分别写对应的Converter:

import org.modelmapper.Converter;
import org.modelmapper.spi.MappingContext;

// Animal的int类型category转AnimalDto的String类型category
Converter<Integer, String> intToCategoryConverter = new Converter<>() {
    @Override
    public String convert(MappingContext<Integer, String> context) {
        return Category.values()[context.getSource()].toString();
    }
};

// AnimalDto的String类型category转Animal的int类型category
Converter<String, Integer> categoryToIntConverter = new Converter<>() {
    @Override
    public Integer convert(MappingContext<String, Integer> context) {
        return Category.valueOf(context.getSource()).ordinal();
    }
};

// Animal的String类型color转AnimalDto的int类型color
Converter<String, Integer> colorToIntConverter = new Converter<>() {
    @Override
    public Integer convert(MappingContext<String, Integer> context) {
        return Color.valueOf(context.getSource()).ordinal();
    }
};

// AnimalDto的int类型color转Animal的String类型color
Converter<Integer, String> intToColorConverter = new Converter<>() {
    @Override
    public String convert(MappingContext<Integer, String> context) {
        return Color.values()[context.getSource()].toString();
    }
};

3. 配置ModelMapper并注册转换器

把转换器注册到ModelMapper实例里,顺便配置一下字段访问策略(如果你的实体/DTO用私有属性+getter/setter的话):

import org.modelmapper.ModelMapper;
import org.modelmapper.config.Configuration.AccessLevel;

ModelMapper modelMapper = new ModelMapper();

// 配置允许访问私有字段,用严格匹配策略避免意外映射
modelMapper.getConfiguration()
    .setFieldMatchingEnabled(true)
    .setFieldAccessLevel(AccessLevel.PRIVATE)
    .setMatchingStrategy(org.modelmapper.MatchingStrategies.STRICT);

// 把转换器绑定到对应的类转换场景
modelMapper.addConverter(intToCategoryConverter, Animal.class, AnimalDto.class);
modelMapper.addConverter(categoryToIntConverter, AnimalDto.class, Animal.class);
modelMapper.addConverter(colorToIntConverter, Animal.class, AnimalDto.class);
modelMapper.addConverter(intToColorConverter, AnimalDto.class, Animal.class);

4. 编写简洁的转换方法

现在转换逻辑就超简单了,直接调用ModelMapper的map方法就行,再也不用手动逐个set属性了:

public class AnimalTransformer {
    // 静态初始化ModelMapper,确保全局只初始化一次
    private static final ModelMapper modelMapper;

    static {
        modelMapper = new ModelMapper();
        // 重复上面的配置和转换器注册逻辑
        modelMapper.getConfiguration()
            .setFieldMatchingEnabled(true)
            .setFieldAccessLevel(AccessLevel.PRIVATE)
            .setMatchingStrategy(org.modelmapper.MatchingStrategies.STRICT);

        // 注册转换器(用Lambda简化写法)
        Converter<Integer, String> intToCategoryConverter = ctx -> Category.values()[ctx.getSource()].toString();
        Converter<String, Integer> categoryToIntConverter = ctx -> Category.valueOf(ctx.getSource()).ordinal();
        Converter<String, Integer> colorToIntConverter = ctx -> Color.valueOf(ctx.getSource()).ordinal();
        Converter<Integer, String> intToColorConverter = ctx -> Color.values()[ctx.getSource()].toString();

        modelMapper.addConverter(intToCategoryConverter, Animal.class, AnimalDto.class);
        modelMapper.addConverter(categoryToIntConverter, AnimalDto.class, Animal.class);
        modelMapper.addConverter(colorToIntConverter, Animal.class, AnimalDto.class);
        modelMapper.addConverter(intToColorConverter, AnimalDto.class, Animal.class);
    }

    // Entity转DTO
    public static AnimalDto animalEntityToDto(Animal animal) {
        return modelMapper.map(animal, AnimalDto.class);
    }

    // DTO转Entity
    public static Animal animalDtoToEntity(AnimalDto animalDto) {
        return modelMapper.map(animalDto, Animal.class);
    }
}

为啥这方案比手动转换好?

  • 少写重复代码:新增属性时,只要类型匹配或者加个新转换器就行,不用再堆一堆set方法
  • 可维护性拉满:转换器可以复用,所有映射配置集中管理
  • 符合开闭原则:加新的转换逻辑不用改原有代码,只需要新增Converter就行

内容的提问来源于stack exchange,提问作者Nitish Prajapati

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 19:03:11