標題可能不太具有描述性,但我會嘗試恢復我的問題。
因此,我正在嘗試使用 Java 規范創建動態查詢。在我的情況下,帶有過濾器的 DTO 來自 REST 端點,對于每個過濾器,我都試圖創建這樣的規范:
private Specification<TrafficData> buildSpecificationQuery(TrafficDataRequestDTO requestDTO) {
List<Specification<TrafficData>> specificationList = new ArrayList<>();
requestDTO.getFilters().forEach(filter -> {
specificationList.add(createSpecification(filter));
});
Specification<TrafficData> specification = Specification.where(specificationList.remove(0));
specificationList.forEach(specification::and);
return specification;
}
private Specification<TrafficData> createSpecification(final TrafficDataFilterDTO input) {
switch (input.getOperator()) {
case EQUALS:
return (root, query, criteriaBuilder) -> criteriaBuilder.equal(root.get(input.getFieldName()), input.getValue());
case NOT_EQUALS:
return (root, query, criteriaBuilder) ->
criteriaBuilder.notEqual(root.get(input.getFieldName()), input.getValue());
case STARTS_WITH:
return (root, query, criteriaBuilder) ->
criteriaBuilder.like(root.get(input.getFieldName()), input.getValue() "%");
case ENDS_WITH:
return (root, query, criteriaBuilder) ->
criteriaBuilder.like(root.get(input.getFieldName()), "%" input.getValue());
case CONTAINS:
return (root, query, criteriaBuilder) ->
criteriaBuilder.like(root.get(input.getFieldName()), "%" input.getValue() "%");
default:
throw new RuntimeException("Operation not supported yet");
}
}
過濾器 DTO 如下所示:
@Data
public class TrafficDataFilterDTO {
private String fieldName;
private TrafficDataFilterOperator operator;
private String value;
}
奇怪的是,當我為兩個不同的過濾器物件呼叫此代碼時,似乎 lambdas 只使用一個input值,并且它僅針對第一個條件回傳一個查詢。這一定是一個與 java lambda 引數相關的問題,但我不能確切地說出它是什么。
所以一個真實的場景:
當我有兩個不同的過濾器物件時:
{ "fieldName": "version", "operator": "EQUALS", "value": "EN_UK" }, { "fieldName": "isManaged", "operator": "EQUALS", "value": true }
方法 createSpecification(final TrafficDataFilterDTO input) 被呼叫兩次,具有正確的輸入值(對于每個過濾器),但包含 lambda 的行
criteriaBuilder.equal(root.get(input.getFieldName()), input.getValue());被第一個過濾器物件呼叫兩次
等待解決方案和解釋為什么會發生這種情況。
uj5u.com熱心網友回復:
Specificiation.and()回傳一個新的Specification,因此您加入規范的代碼不起作用。
您需要像這樣加入規范:
Specification<TrafficData> specification = Specification.where(specificationList.remove(0));
return specificationList.stream().reduce(specification, Specification::and);
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/369650.html
