我有一个Spring Boot Web API,它使用querydsl从关系数据库中获取结果,在我的例子中是MariaDB .
这是服务:
@Override
public List fetchProductAuditTrailResult(TxnRequestDTO<HeaderDTO, ProductAuditTrailReportRequestDTO> request)
throws ParseException {
List<LIHistoryProductEntity> txnResponse = new ArrayList<LIHistoryProductEntity>();
logger.info("Entered ReportService.fetchProductAuditTrailResult()");
QLIHistoryProductEntity qLiHistoryProductEntity = QLIHistoryProductEntity.lIHistoryProductEntity;
Map<String, StringPath> notNullInputMap = getFieldMappingForProductAuditReport(request);
logger.info("Received non empty map for input fields");
txnResponse = jpaQueryFactory.selectFrom(qLiHistoryProductEntity)
.where(buildExpressionForProductAuditReport(notNullInputMap, qLiHistoryProductEntity, request)).fetch();
for (LIHistoryProductEntity entry : txnResponse) {
entry.setPlanType(properties.getPlanType().get(entry.getPlanType()));
entry.setMaintenanceStatus(properties.getMaintenaceStatus().get(entry.getMaintenanceStatus()));
}
logger.info("EXITING ReportService.fetchProductAuditTrailResult()");
return txnResponse;
}
private Predicate buildExpressionForProductAuditReport(Map<String, StringPath> notNullInputMap,
QLIHistoryProductEntity entity, TxnRequestDTO<HeaderDTO, ProductAuditTrailReportRequestDTO> request)
throws ParseException {
BooleanExpression expression = null;
Map<String, StringPath> fieldMapping = getFieldMappingForProductAuditReport(request);
ProductAuditTrailReportRequestDTO searchDTO = request.getTxnRequest();
for (Map.Entry<String, String> entry : searchDTO.entrySet()) {
String fieldName = entry.getKey();
String fieldValue = entry.getValue();
if (!StringUtils.isEmpty(fieldValue) && fieldMapping.containsKey(fieldName)) {
expression = (expression != null) ? expression.and(fieldMapping.get(fieldName).eq(fieldValue))
: fieldMapping.get(fieldName).eq(fieldValue);
}
}
QLIHistoryProductEntity qLIProductEntity = QLIHistoryProductEntity.lIHistoryProductEntity;
if (searchDTO.containsKey(RECEIVED_DATE_FROM) && !searchDTO.get(RECEIVED_DATE_FROM).isEmpty()
&& !searchDTO.get(RECEIVED_DATE_TO).isEmpty() && searchDTO.containsKey(RECEIVED_DATE_TO)) {
BooleanExpression dateBetween = qLIProductEntity.recordTimestamp.between(
formatter.parse(searchDTO.get(RECEIVED_DATE_FROM)),
formatter.parse(searchDTO.get(RECEIVED_DATE_TO)));
expression = (expression != null) ? expression.and(dateBetween) : dateBetween;
}
return expression;
}
private Map<String, StringPath> getFieldMappingForProductAuditReport(
TxnRequestDTO<HeaderDTO, ProductAuditTrailReportRequestDTO> request) {
QLIHistoryProductEntity qLIProductEntity = QLIHistoryProductEntity.lIHistoryProductEntity;
Map<String, StringPath> fieldMapping = new HashMap<>();
fieldMapping.put("productCode", qLIProductEntity.productCode);
fieldMapping.put("insurerComponentCode", qLIProductEntity.componentCode);
fieldMapping.put("insurerName", qLIProductEntity.insurerName);
fieldMapping.put("productName", qLIProductEntity.productName);
return fieldMapping;
}
这是实体:
@Entity
@Table(name = "DBS_LI_PRODUCT_HISTORY")
public class LIHistoryProductEntity extends LIProductEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "PRODUCT_CODE")
private String productCode;
@Column(name = "COMPONENT_CODE")
private String componentCode;
//getters and setters
映射的超类:
@MappedSuperclass
public class LIProductEntity {
@Column(name = "RECORD_STATUS")
private String recordStatus;
@Column(name = "PLAN_TYPE")
private String planType;
@Column(name = "MAINTENANCE_INDICATOR")
private String maintenanceStatus;
@Column(name = "PRODUCT_NAME")
private String productName;
@Column(name = "INSURER_NAME")
private String insurerName;
@Column(name = "RECORD_TIMESTAMP")
private Date recordTimestamp;
@Column(name = "INSURER_CODE")
private String insurerCode;
@Column(name = "COUNTRY_CODE")
private String insurerCountryCode;
@Column(name = "GROUP_POLICY_INDICATOR")
private String groupPolicyIndicator;
@Column(name = "GROUP_POLICY_NO")
private String groupPolicyNo;
@Column(name = "PRODUCT_TENURE")
private String productTenure;
@Column(name = "LAUNCH_START_DATE")
private Date launchStartDate;
@Column(name = "LAUNCH_END_DATE")
private Date launchEndDate;
@Column(name = "MAIN_CURRENCY_TYPE")
private String mainCurrencyType;
@Column(name = "IBMB_TEMPLATE_NAME")
private String ibmbTemplateName;
@Column(name = "IBMB_TEMPLATE_ID")
private String ibmbTemplateId;
@Column(name = "CUSTOMER_SEGMENT_MM")
private Character customerSegmentMM;
@Column(name = "CUSTOMER_SEGMENT_TR")
private Character customerSegmentTR;
@Column(name = "CUSTOMER_SEGMENT_TPC")
private Character customerSegmentTPC;
@Column(name = "CUSTOMER_SEGMENT_PB")
private Character customerSegmentPB;
@Column(name = "POLICY_CATEGORY")
private String policyCategory;
@Column(name = "COVERAGE_TYPE")
private String coverageType;
@Column(name = "PRODUCT_GROUPING")
private String productCategory;
@Column(name = "REMARKS")
private String remarks;
@Column(name = "LAST_UPDATED_BY")
private String lastUpdatedBy;
@Column(name = "LAST_UPDATED_DATE_TIME")
private Date lastUpdatedDateTime;
@Column(name = "APPROVED_BY")
private String approvedBy;
@Column(name = "APPROVED_DATE_TIME")
private Date lastApprovedDate;
@Column(name = "BANK_ACCOUNT_NO")
private String bankAccountNo;
//getters and setters
这里的问题是,一旦querydsl占用内存,它就不会放弃它,这会导致问题 . 我们已经不得不将我们的应用程序从1GB内存扩展到2GB内存,即使这还不够 .
My usecase :
请求正文将包含可能有或没有值的搜索过滤器,我们必须根据这些值从DB中获取结果 .
请帮助建议一个更好的替代方案,它将在CPU空闲时释放内存 .
我想过使用JPQL但不知道如何编写查询,因为可能存在多种组合,因为所有搜索字段可能有也可能没有值 .
或者建议使用旧的JDBC?
感谢帮助和建议 .