如何使用 QueryDsl 在查询中按 id 删除重复行
how to delete a repeat row by id in a query, using QueryDsl
我卡在获取查询中 codeRecurrence 的唯一行的查询中。
public JPQLQuery<RecurrenceErrorVO> getQueryErrorRecurrence(Integer companyCode, Collection<SearchModelDTO<Object>> searchModelDTOs) {
//Entities
QRecurrencyEntity qRecurrencyEntity = QRecurrencyEntity.recurrencyEntity;
QSubscriptionEntity qSubscriptionEntity = QSubscriptionEntity.subscriptionEntity;
QRecurrencyDetailsEntity qRecurrencyDetailsEntity = QRecurrencyDetailsEntity.recurrencyDetailsEntity;
QSubcriptionProductEntity qSubcriptionProductEntity = QSubcriptionProductEntity.subcriptionProductEntity;
QArticleEntity qArticleEntity = QArticleEntity.articleEntity;
QCatalogoValorDTO qStatusGeneral = new QCatalogoValorDTO("qStatusGeneral");
QCatalogoValorDTO qrecurrenceType = new QCatalogoValorDTO("qrecurrenceType");
QCatalogoValorDTO qbusinessTypeDTO = new QCatalogoValorDTO("qbusinessTypeDTO");
QCatalogoValorDTO qcausalCatalogType = new QCatalogoValorDTO("qcausalCatalogType");
//data
JPQLQuery<RecurrenceErrorVO> query = from(qRecurrencyDetailsEntity).select(
Projections.bean(RecurrenceErrorVO.class, qRecurrencyEntity.codeRecurrency.as("codeRecurrence"),
qRecurrencyDetailsEntity.codeDetailsTransaction.as("codeRecurrenceDetail"),
qRecurrencyEntity.statusGeneralValue.as("statusGeneralValue"),
qRecurrencyEntity.processDate.as("dateRecurrence"),
qRecurrencyDetailsEntity.transactionDate.as("dateTransaction"),
qSubscriptionEntity.contractIdentifier,
qSubcriptionProductEntity.articleEntity.itemDescription.as("productName"),
qSubscriptionEntity.numberDocumentClient.as("clientDocNumber"),
qSubscriptionEntity.customerName.as("clientName"),
qSubscriptionEntity.subscriptionValue.as("subscriptionValue"),
qSubscriptionEntity.statusSubscriptionValue,
qStatusGeneral.nombreCatalogoValor.as("statusGeneralDescription"),
qRecurrencyEntity.originRecurrenceValue.as("originRecurrenceValue"),
qRecurrencyEntity.value,
qRecurrencyEntity.status,
qRecurrencyDetailsEntity.causalValue.as("codeCausalValue"),
qRecurrencyDetailsEntity.causalType.as("codeCausalType"),
qbusinessTypeDTO.nombreCatalogoValor.as("marca"),
qcausalCatalogType.nombreCatalogoValor.as("causalValue"),
qrecurrenceType.nombreCorto.as("nombreCorto"),
qrecurrenceType.nombreCatalogoValor.as("transactionType")))
//join
query.leftJoin(qRecurrencyDetailsEntity.recurrencyEntity, qRecurrencyEntity)
.leftJoin(qRecurrencyEntity.subscriptionEntity, qSubscriptionEntity)
.leftJoin(qRecurrencyEntity.subcriptionProductEntity, qSubcriptionProductEntity)
.innerJoin(qSubcriptionProductEntity.articleEntity, qArticleEntity)
.innerJoin(qRecurrencyEntity.statusGeneral, qStatusGeneral)
.innerJoin(qSubcriptionProductEntity.businessTypeDTO, qbusinessTypeDTO)
.innerJoin(qRecurrencyDetailsEntity.recurrenceType, qrecurrenceType)
.innerJoin(qRecurrencyDetailsEntity.causalCatalogType, qcausalCatalogType)
;
BooleanBuilder where = new BooleanBuilder();
where.and(qRecurrencyEntity.statusGeneralValue.ne(SirConstants.RECURRENCE_STATUS_FIN));
where.and(qRecurrencyEntity.statusGeneralValue.ne(SirConstants.RECURRENCE_STATUS_SIN_CUPO));
where.and(qRecurrencyEntity.statusGeneralValue.ne(SirConstants.RECURRENCE_STATUS_FIN_WITH_OBSERVATION));
where.and(qRecurrencyDetailsEntity.statusRecurrencyDetailsValue.ne(SirConstants.ZERO.toString()));
where.and(qRecurrencyEntity.originRecurrenceValue.eq(SirConstants.RECURRENCE_ORIGIN_INTERNO));
where.and(qRecurrencyEntity.companyCode.eq(companyCode));
where.and(qRecurrencyEntity.status.isTrue());
SearchModelUtil.addDynamicWhere(searchModelDTOs, where, RecurrencyEntity.class, "recurrencyEntity");
query.where(where);
query.orderBy(qRecurrencyEntity.codeRecurrency.desc(), qRecurrencyDetailsEntity.codeDetailsTransaction.desc());
return query;
}
这是我当前的代码,
而这个returns的值作为下一个table
CODERECURRENCY|CODEDCURRENCYDETAILS|STATUSGENERALVALUE|PROCESSDATE |TRANSACTIONDATE
--------------|--------------------|------------------|-------------------|-------------------
16202| 14510|ERR |2020-10-23 12:08:26|2020-11-27 16:53:57
16202| 14094|ERR |2020-10-23 12:08:26|2020-10-23 12:08:47
16202| 14093|ERR |2020-10-23 12:08:26|2020-10-23 12:08:41
16201| 14088|EXR |2020-10-22 23:51:58|2020-10-22 23:53:43
16201| 14087|EXR |2020-10-22 23:51:58|2020-10-22 23:53:37
16201| 14083|EXR |2020-10-22 23:51:58|2020-10-22 23:53:15
16201| 14082|EXR |2020-10-22 23:51:58|2020-10-22 23:53:09
16201| 14078|EXR |2020-10-22 23:51:58|2020-10-22 23:52:47
16201| 14077|EXR |2020-10-22 23:51:58|2020-10-22 23:52:41
16201| 14073|EXR |2020-10-22 23:51:58|2020-10-22 23:52:19
16201| 14072|EXR |2020-10-22 23:51:58|2020-10-22 23:52:13
16123| 13675|ERR |2020-10-01 17:06:17|2020-10-01 17:06:28
16050| 13511|ERR |2020-09-21 14:11:31|2020-09-21 14:11:31
16043| 13470|EXR |2020-09-16 10:04:20|2020-09-16 10:07:00
codeRecurrency 需要一行,我使用代码删除重复行,但如果我将 JpqlQuery 转换为列表并且这会更改 web 服务中显示的值的结果,我需要使用分页。
这段代码展示了查询的用法。
private PageResultVO<RecurrenceErrorVO> findPagedRE(JPQLQuery<RecurrenceErrorVO> query, Pageable pageable) {
List<RecurrenceErrorVO> list = Objects.requireNonNull(getQuerydsl()).applyPagination(
pageable, query).fetch();
Page<RecurrenceErrorVO> page = PageableExecutionUtils.getPage(list,
pageable,
query::fetchCount);
return new PageResultVO<>(page.getContent(), page.getPageable(), page.getTotalElements());
}
我将此代码用作带分页的 web 服务,以便将来公开。
我该怎么办?
您需要使用带有 group by 子句的聚合函数(不能与 QueryDSL for JPA 中的 query::fetchCount
结合使用)或带有 window 函数的不同元组(这需要要注册的自定义函数)。即便如此,您也可能会为投影中的实体投影而苦恼。例如,您不能执行 MAX(someEntity)
来获取带有 MAX(someEntity.id)
的实体。
使用普通的 Hibernate 和 QueryDSL 无法做到这一点,但可以使用 Blaze-Persistence integration for QueryDSL 来完成。使用此 Hibernate 扩展,您可以在指定 GROUP BY
或 HAVING
子句的查询中使用 window 函数或使用 fetchCount
。您还可以利用 Blaze-Persistence CTE 或子查询横向连接来创建查询。
我卡在获取查询中 codeRecurrence 的唯一行的查询中。
public JPQLQuery<RecurrenceErrorVO> getQueryErrorRecurrence(Integer companyCode, Collection<SearchModelDTO<Object>> searchModelDTOs) {
//Entities
QRecurrencyEntity qRecurrencyEntity = QRecurrencyEntity.recurrencyEntity;
QSubscriptionEntity qSubscriptionEntity = QSubscriptionEntity.subscriptionEntity;
QRecurrencyDetailsEntity qRecurrencyDetailsEntity = QRecurrencyDetailsEntity.recurrencyDetailsEntity;
QSubcriptionProductEntity qSubcriptionProductEntity = QSubcriptionProductEntity.subcriptionProductEntity;
QArticleEntity qArticleEntity = QArticleEntity.articleEntity;
QCatalogoValorDTO qStatusGeneral = new QCatalogoValorDTO("qStatusGeneral");
QCatalogoValorDTO qrecurrenceType = new QCatalogoValorDTO("qrecurrenceType");
QCatalogoValorDTO qbusinessTypeDTO = new QCatalogoValorDTO("qbusinessTypeDTO");
QCatalogoValorDTO qcausalCatalogType = new QCatalogoValorDTO("qcausalCatalogType");
//data
JPQLQuery<RecurrenceErrorVO> query = from(qRecurrencyDetailsEntity).select(
Projections.bean(RecurrenceErrorVO.class, qRecurrencyEntity.codeRecurrency.as("codeRecurrence"),
qRecurrencyDetailsEntity.codeDetailsTransaction.as("codeRecurrenceDetail"),
qRecurrencyEntity.statusGeneralValue.as("statusGeneralValue"),
qRecurrencyEntity.processDate.as("dateRecurrence"),
qRecurrencyDetailsEntity.transactionDate.as("dateTransaction"),
qSubscriptionEntity.contractIdentifier,
qSubcriptionProductEntity.articleEntity.itemDescription.as("productName"),
qSubscriptionEntity.numberDocumentClient.as("clientDocNumber"),
qSubscriptionEntity.customerName.as("clientName"),
qSubscriptionEntity.subscriptionValue.as("subscriptionValue"),
qSubscriptionEntity.statusSubscriptionValue,
qStatusGeneral.nombreCatalogoValor.as("statusGeneralDescription"),
qRecurrencyEntity.originRecurrenceValue.as("originRecurrenceValue"),
qRecurrencyEntity.value,
qRecurrencyEntity.status,
qRecurrencyDetailsEntity.causalValue.as("codeCausalValue"),
qRecurrencyDetailsEntity.causalType.as("codeCausalType"),
qbusinessTypeDTO.nombreCatalogoValor.as("marca"),
qcausalCatalogType.nombreCatalogoValor.as("causalValue"),
qrecurrenceType.nombreCorto.as("nombreCorto"),
qrecurrenceType.nombreCatalogoValor.as("transactionType")))
//join
query.leftJoin(qRecurrencyDetailsEntity.recurrencyEntity, qRecurrencyEntity)
.leftJoin(qRecurrencyEntity.subscriptionEntity, qSubscriptionEntity)
.leftJoin(qRecurrencyEntity.subcriptionProductEntity, qSubcriptionProductEntity)
.innerJoin(qSubcriptionProductEntity.articleEntity, qArticleEntity)
.innerJoin(qRecurrencyEntity.statusGeneral, qStatusGeneral)
.innerJoin(qSubcriptionProductEntity.businessTypeDTO, qbusinessTypeDTO)
.innerJoin(qRecurrencyDetailsEntity.recurrenceType, qrecurrenceType)
.innerJoin(qRecurrencyDetailsEntity.causalCatalogType, qcausalCatalogType)
;
BooleanBuilder where = new BooleanBuilder();
where.and(qRecurrencyEntity.statusGeneralValue.ne(SirConstants.RECURRENCE_STATUS_FIN));
where.and(qRecurrencyEntity.statusGeneralValue.ne(SirConstants.RECURRENCE_STATUS_SIN_CUPO));
where.and(qRecurrencyEntity.statusGeneralValue.ne(SirConstants.RECURRENCE_STATUS_FIN_WITH_OBSERVATION));
where.and(qRecurrencyDetailsEntity.statusRecurrencyDetailsValue.ne(SirConstants.ZERO.toString()));
where.and(qRecurrencyEntity.originRecurrenceValue.eq(SirConstants.RECURRENCE_ORIGIN_INTERNO));
where.and(qRecurrencyEntity.companyCode.eq(companyCode));
where.and(qRecurrencyEntity.status.isTrue());
SearchModelUtil.addDynamicWhere(searchModelDTOs, where, RecurrencyEntity.class, "recurrencyEntity");
query.where(where);
query.orderBy(qRecurrencyEntity.codeRecurrency.desc(), qRecurrencyDetailsEntity.codeDetailsTransaction.desc());
return query;
}
这是我当前的代码, 而这个returns的值作为下一个table
CODERECURRENCY|CODEDCURRENCYDETAILS|STATUSGENERALVALUE|PROCESSDATE |TRANSACTIONDATE
--------------|--------------------|------------------|-------------------|-------------------
16202| 14510|ERR |2020-10-23 12:08:26|2020-11-27 16:53:57
16202| 14094|ERR |2020-10-23 12:08:26|2020-10-23 12:08:47
16202| 14093|ERR |2020-10-23 12:08:26|2020-10-23 12:08:41
16201| 14088|EXR |2020-10-22 23:51:58|2020-10-22 23:53:43
16201| 14087|EXR |2020-10-22 23:51:58|2020-10-22 23:53:37
16201| 14083|EXR |2020-10-22 23:51:58|2020-10-22 23:53:15
16201| 14082|EXR |2020-10-22 23:51:58|2020-10-22 23:53:09
16201| 14078|EXR |2020-10-22 23:51:58|2020-10-22 23:52:47
16201| 14077|EXR |2020-10-22 23:51:58|2020-10-22 23:52:41
16201| 14073|EXR |2020-10-22 23:51:58|2020-10-22 23:52:19
16201| 14072|EXR |2020-10-22 23:51:58|2020-10-22 23:52:13
16123| 13675|ERR |2020-10-01 17:06:17|2020-10-01 17:06:28
16050| 13511|ERR |2020-09-21 14:11:31|2020-09-21 14:11:31
16043| 13470|EXR |2020-09-16 10:04:20|2020-09-16 10:07:00
codeRecurrency 需要一行,我使用代码删除重复行,但如果我将 JpqlQuery 转换为列表并且这会更改 web 服务中显示的值的结果,我需要使用分页。
这段代码展示了查询的用法。
private PageResultVO<RecurrenceErrorVO> findPagedRE(JPQLQuery<RecurrenceErrorVO> query, Pageable pageable) {
List<RecurrenceErrorVO> list = Objects.requireNonNull(getQuerydsl()).applyPagination(
pageable, query).fetch();
Page<RecurrenceErrorVO> page = PageableExecutionUtils.getPage(list,
pageable,
query::fetchCount);
return new PageResultVO<>(page.getContent(), page.getPageable(), page.getTotalElements());
}
我将此代码用作带分页的 web 服务,以便将来公开。
我该怎么办?
您需要使用带有 group by 子句的聚合函数(不能与 QueryDSL for JPA 中的 query::fetchCount
结合使用)或带有 window 函数的不同元组(这需要要注册的自定义函数)。即便如此,您也可能会为投影中的实体投影而苦恼。例如,您不能执行 MAX(someEntity)
来获取带有 MAX(someEntity.id)
的实体。
使用普通的 Hibernate 和 QueryDSL 无法做到这一点,但可以使用 Blaze-Persistence integration for QueryDSL 来完成。使用此 Hibernate 扩展,您可以在指定 GROUP BY
或 HAVING
子句的查询中使用 window 函数或使用 fetchCount
。您还可以利用 Blaze-Persistence CTE 或子查询横向连接来创建查询。