【问题标题】:Best way to return a complex dto in hibernate/jpa method with many data在 hibernate/jpa 方法中返回具有许多数据的复杂 dto 的最佳方法
【发布时间】:2021-02-27 22:25:13
【问题描述】:

我有一个服务方法:

@Transactional
    @Override
    public List<DLevelsDTO> getAll(InputDTO json ){
        String idAdminPK = json.getIdAmminstrazionePK();
        Long idAdminPKDecrypted = Long.parseLong(EncrypterUtils.decrypt(idAdminPK));
        
        List<DLevels> entityList = dLevelsRepository.findAll();
        List<DLevelsDTO> resultList = new ArrayList<DLevelsDTO>();
        for(DLevels entity : entityList) {
            
            DLevelsDTO dto = Converter.convert(entity, DLevelsDTO.class);
            
            Optional<List<DUnitEntity>> optHList = dUnitsRepository.findUnit(idAdminPKDecrypted, entity.getCodiLevel());
            
            if (optHList.isPresent()) {
                
                List<DUnitDTO> jsonResponseList = new ArrayList<DUnitDTO>();
                
                List<DUnitEntity> entityHList =optHList.get();
                for(DUnitEntity entityH : entityHList) {
                    DUnitDTO jsonResponse = new DUnitDTO();
                    jsonResponse.setIdUnit(EncrypterUtils.encrypt(entityH.getSequIdUnitaOrganizzativaH()));
                    jsonResponse.setFkAdmin(EncrypterUtils.encrypt(entityH.getFkAdmin().longValue()));
                    jsonResponse.setCodiCodiceUo(entityH.getCodiCodiceUo());
                    jsonResponse.setDescDenomUo(entityH.getDescDenomUo());
                    
                    jsonResponseList.add(jsonResponse);

                }
                dto.setList(jsonResponseList);
            }
            resultList.add(dto);
        }
        return resultList;
    }

在第一次调用 jpa 存储库 ( findAll ) 时,结果长度 > 4000 行 在这一行的 for-cycle 中,对于每一个我搜索另一个对象,并且这里我有大量数据。

最后的 dto 是:

List resultList = new ArrayList() // > 4000 行

每个对象都有 List entityHList // > 1000 行

服务响应时间为 10-15 秒...

有减少服务时间的最佳方法吗? 如果我使用 Oracle 表视图或递归查询而不是 Java?

感谢回复

【问题讨论】:

  • 你能分页吗?

标签: spring-boot hibernate jpa spring-data-jpa spring-data


【解决方案1】:

这最好通过 DTO 方法和执行连接提取的专用查询来解决。

话虽如此,我认为这是Blaze-Persistence Entity Views 的完美用例。

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

使用 Blaze-Persistence Entity-Views 的用例的 DTO 模型可能如下所示:

@EntityView(DLevels.class)
public interface DLevelsDTO {
    @IdMapping
    Long getId();
    String getName();

    // Not sure what the logic is in dUnitsRepository.findUnit()
    @Mapping("units[id = :idAdminPKDecrypted AND codiLevel = VIEW(codiLevel)]")
    List<DUnitDTO> getList();

    @EntityView(DUnitEntity.class)
    public abstract class DUnitDTO {
        private final long sequIdUnitaOrganizzativaH;
        private final long fkAdmin;

        public DUnitDTO(
            @Mapping("sequIdUnitaOrganizzativaH") long sequIdUnitaOrganizzativaH,
            @Mapping("fkAdmin") long fkAdmin
        ) {
            this.sequIdUnitaOrganizzativaH = EncrypterUtils.encrypt(sequIdUnitaOrganizzativaH);
            this.fkAdmin = EncrypterUtils.encrypt(fkAdmin);
        }

        @IdMapping
        public abstract Long getId();
        public abstract String getCodiCodiceUo();
        public abstract String getDescDenomUo();
        public long getSequIdUnitaOrganizzativaH() {
            return sequIdUnitaOrganizzativaH;
        }
        public long getFkAdmin () {
            return fkAdmin;
        }
    }
}

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

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

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

List<DLevelsDTO> findAll();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-30
    • 2012-11-19
    • 1970-01-01
    • 2011-02-19
    • 1970-01-01
    • 2019-12-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多