如何从ModelMapper迁移到MapStruct?

问题描述 投票:0回答:1

我目前正在使用 ModelMapper。从我的角度来看,这非常用户友好。但是,由于性能问题,我需要迁移到 MapStruct。想象一下我有如下

Tariff
课程

@Setter @Getter @Builder @ToString
@AllArgsConstructor @NoArgsConstructor
@Entity
@Table(name = "tariff")
public class Tariff {
    @Id
    @Column(name = "id")
    private String id;

    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "id_energy_mix")
    private EnergyMix energyMix;

我的

TariffDTO
如下

@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class TariffDTO {
    @JsonProperty("id")
    @SerializedName("id")
    private String id;

    @JsonProperty("id_energy_mix")
    @SerializedName("id_energy_mix")
    private EnergyMixDTO energyMix;

当我需要将 Tariff 转换为 TariffDTO 时,我使用 ModelMapper 如下

    public TariffDTO mapperTariffToDTO(Tariff tariff) {
        ModelMapper modelMapper = new ModelMapper();
        TypeMap<Tariff, TariffDTO> typeMap = modelMapper.createTypeMap(Tariff.class, TariffDTO.class);

        if (tariff.getEnergyMix() != null) {
            typeMap.addMappings(mapper -> mapper.<EnergyMixDTO>map(src -> mapperEnergyMixToDTO(tariff.getEnergyMix()),
                    (dest, v) -> dest.setEnergyMix(v)));
        }
        return modelMapper.map(tariff, TariffDTO.class);

    public EnergyMixDTO mapperEnergyMixToDTO(EnergyMix energyMix) {
        ModelMapper modelMapper = new ModelMapper();
        return modelMapper.map(energyMix, EnergyMixDTO.class);
    }

这些代码块给了我预期的输出。我不需要在 ModelMapper 中包含

id
的映射。

当我尝试使用 MapStruct 时,我需要创建一个接口并为每个属性添加映射,如下所示

    @Mapping(source = "id", target = "id")
    // I want to add EnergyMix to EnergyMixDTO too
    TariffDTO mapperTariffToDTO(Tariff tariff);

我的第一个问题,有没有办法避免 MapStruct 中的样板代码?我的意思是,如果我可以避免为相同的属性名称添加映射。另一方面,我需要为

EnergyMix
EnergyMixDTO
创建一个映射器,并且我可能需要在项目中的不同类中使用它。因此,我想为
EnergyMix
EnergyMixDTO
映射器创建另一个类,并在
Tariff
TariffDTO
映射器中使用它。这可能吗?

java spring-boot mapstruct
1个回答
0
投票

就您而言,您需要 2 个映射器:

EnergyMixMapper:

@Mapper(componentModel = MappingConstants.ComponentModel.SPRING, injectionStrategy = InjectionStrategy.CONSTRUCTOR)
public interface EnergyMixMapper {

    EnergyMixDto toDto(EnergyMix entity);

}

关税映射器:

@Mapper(componentModel = MappingConstants.ComponentModel.SPRING, 
        injectionStrategy = InjectionStrategy.CONSTRUCTOR, 
        uses = { EnergyMixMapper.class })
public interface TariffMapper {

    TariffDto toDto(Tariff entity);

}

这就是您所需要的!正如您所看到的,如果实体和 dto 具有相同的字段名称,那么非常简单,无需样板代码。

两个映射器的实现将是:

EnergyMixMapperImpl:

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2024-02-01T18:48:14+0100",
    comments = "version: 1.5.5.Final, compiler: Eclipse JDT (IDE) 3.36.0.v20231114-0937, environment: Java 17.0.5 (Eclipse Adoptium)"
)
@Component
public class EnergyMixMapperImpl implements EnergyMixMapper {

    @Override
    public EnergyMixDto toDto(EnergyMix entity) {
        if ( entity == null ) {
            return null;
        }

        EnergyMixDto.EnergyMixDtoBuilder<?, ?> energyMixDto = EnergyMixDto.builder();

        energyMixDto.fieldA( entity.getFieldA() );
        energyMixDto.fieldB( entity.getFieldB() );
        energyMixDto.id( entity.getId() );

        return energyMixDto.build();
    }
} 

TariffMapperImpl:

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2024-02-01T18:48:14+0100",
    comments = "version: 1.5.5.Final, compiler: Eclipse JDT (IDE) 3.36.0.v20231114-0937, environment: Java 17.0.5 (Eclipse Adoptium)"
)
@Component
public class TariffMapperImpl implements TariffMapper {

    private final EnergyMixMapper energyMixMapper;

    @Autowired
    public TariffMapperImpl(EnergyMixMapper energyMixMapper) {

        this.energyMixMapper = energyMixMapper;
    }

    @Override
    public TariffDto toDto(Tariff entity) {
        if ( entity == null ) {
            return null;
        }

        TariffDto.TariffDtoBuilder<?, ?> tariffDto = TariffDto.builder();

        tariffDto.energyMix( energyMixMapper.toDto( entity.getEnergyMix() ) );
        tariffDto.id( entity.getId() );

        return tariffDto.build();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.