使用嵌套 DTO 将实体映射到 DTO

时间:2021-01-11 11:18:00

标签: spring hibernate

我有一个关系(重)数据库模型,其中包含很多表依赖项和外键。 我们选择使用 DTO 是为了简化前端的数据表示并隐藏数据库模式的复杂性。

但是我们有带有嵌套 DTO 的 DTO。我们有 Mapper 实现类,可以使用小型业务/功能逻辑设置数据。

问题是,映射器类调用映射器(等)是否是一个好习惯,还是让主类处理所有映射器类的最佳方式? (例 1 或 2)

示例 1:

@Component
public class ActorMapperImpl implements ActorMapper {

    @Autowired
    private InsurerMapper insurerMapper;

    @Autowired
    private PersonMapper personMapper;

    @Autowired
    private CorrespondentMapper correspondentMapper;

    ....

    @Override
    public ActorDto mapToDto(Acteur actor) {
        final ActorDto actorDto;
        
        if (actor != null) {
            ....
            
            actorDto.setPerson(personMapper.personneToPersonDto(actor.getPersonne()));

            
            if (actor.getInsurer() != null) {
                actorDto.setInsurer(insurerMapper.entityToDto(actor.getInsurer()));
            } else if (actor.getCorrespondantAssureur() != null) {
                actorDto.setInsurer(correspondentMapper.correspondentToInsurerDto(actor.getCorrespondantAssureur()));
            }

            ....

            // intermediate
            final Intermediaire intermediate = actor.getIntermediaire();
            if (intermediate != null) {
                .....
                if (person != null) {
                    intermediateDto = personMapper.personneToPersonDto(person);
                    intermediateDto.setQuality(quality);
                } 
                .....
            }
        .....

示例 2:

@Service
public class FinancialSlipOrchestratorImpl implements FinancialSlipOrchestrator {

    .....
   

    @Autowired
    private FinancialSlipMapper financialSlipMapper;

    @Autowired
    private PersonMapper personMapper;

    

    ..... some public / private methods

    

    private FinancialSlipDto fullMapToDto(FinancialSlip financialSlip) {
        .....
    
    
        // Financial slip
        var financialSlipDto = financialSlipMapper.mapToDto(financialSlip);

        // person
        financialSlipDto.setIssuerPerson(personMapper.personneToPersonDto(financialSlip.getIssuerPerson()));
        
        ....

        // RIB
        financialSlipDto.setRib(ribMapper.mapToDto(financialSlip.getRib()));

        return financialSlipDto;
    }

1 个答案:

答案 0 :(得分:1)

我认为一个映射器可以调用另一个映射器并认为这是 Blaze-Persistence Entity Views 的完美用例。

我创建了该库以允许在 JPA 模型和自定义接口或抽象类定义的模型之间轻松映射,例如类固醇上的 Spring Data Projections。这个想法是,您可以按照自己喜欢的方式定义目标结构(域模型),并通过 JPQL 表达式将属性(getter)映射到实体模型。

您的用例的 DTO 模型可能如下所示,其中包含 Blaze-Persistence Entity-Views:

@EntityView(Acteur.class)
public interface ActorDto {
    @IdMapping
    Long getId();
    String getName();
    PersonDto getPerson();
    default InsurerDto getInsurer() {
        return getMainInsurer() != null ? getMainInsurer(): getCorrespondantAssureur();
    }
    @Mapping("insurer")
    InsurerDto getMainInsurer();
    InsurerDto getCorrespondantAssureur();
    IntermediaireDto getIntermediaire();

    @EntityView(Person.class)
    interface PersonDto {
        @IdMapping
        Long getId();
        String getName();
    }
    @EntityView(Insurer.class)
    interface InsurerDto  {
        @IdMapping
        Long getId();
        String getName();
    }
    @EntityView(Intermediaire.class)
    interface IntermediaireDto {
        @IdMapping
        Long getId();
        String getName();
        Integer getQuality();
        PersonDto getPerson();
    }
}

查询是将实体视图应用于查询的问题,最简单的就是通过 id 查询。

ActorDto a = entityViewManager.find(entityManager, ActorDto.class, id);

Spring Data 集成允许您像使用 Spring Data Projections 一样使用它:https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features

最好的一点是,它只会获取实际需要的数据。

如果您也使用 DTO 来刷新更改,您会很高兴听到 Blaze-Persistence Entity-Views 也以非常有效的方式支持这一点。这将使您摆脱所有那些手动编写的映射器:)

相关问题