过滤/搜索使用规格给出不同的结果
Filter/ search Using Specifications gives different Results
我正在使用动态查询为我的 API 演示项目开发 filter/Search 端点。
这是我的过滤器端点。
@GetMapping("/filter")
public ResponseEntity<List<ProductDto>> filterProducts(@RequestParam("name") String name,
@RequestParam("expiryDatemin") String expiryDatemin, @RequestParam("expiryDatemax") String expiryDatemax,
@RequestParam("type") String type, @RequestParam("quantitymin") String quantityin,
@RequestParam("quantitymin") String quantitymax, @RequestParam("company") String company,
@RequestParam("pricemin") String pricemin, @RequestParam("pricemax") String pricemax) {
return new ResponseEntity<List<ProductDto>>(productgetservice.filterProducts(expiryDatemin, expiryDatemax, name,
type, quantityin, quantitymax, company, pricemin, pricemax), HttpStatus.OK);
}
我想做的是用户可以输入任何元素,并且只显示满足过滤器的数据。
如果用户将所有值都发送为 null 或空,则它应该 return table 的完整数据。
就像在末尾具有最小最大值的变量一样,是在这些间隔之间获取数据。
如果仅输入最小值,则应发送高于该条件的所有数据;如果仅输入最大值,则应显示低于该条件的所有数据。
我的 serviceImpl class 方法如下:
@Override
public List<ProductDto> filterProducts(String expiryDatemin, String expiryDatemax, String name, String type,
String quantitymin, String quantitymax, String company, String pricemin, String pricemax) {
List<Product> products = productrepository.findAll(where(ProductSpecifications
.withExpiryDates(expiryDatemin, expiryDatemax).and(ProductSpecifications.withcompany(company))
.and(ProductSpecifications.withPrices(pricemin, pricemax))
.and(ProductSpecifications.withQuantity(quantitymin, quantitymax))
.and(ProductSpecifications.withType(type))));
return productsListToProductDto(products);
}
我遇到的问题是,当我使用 'and' 发送数据时,它总是 return 一个空数组作为有效负载。
当我用 'or' 替换 and 时,它 returns table 的全部数据作为列表。
这是我的产品规格 class 方法:
public static Specification<Product> withExpiryDates(String expiryDatemin, String expiryDatemax) {
return (root, query, cb) -> {
if ((expiryDatemax.isBlank() || expiryDatemax == null)
&& (expiryDatemin.isBlank() || expiryDatemin == null)) {
return cb.conjunction();
} else if ((expiryDatemax.isBlank() || expiryDatemax == null)) {
return cb.greaterThanOrEqualTo(root.get("expiryDate"), LocalDate.parse(expiryDatemin));
} else if ((expiryDatemin.isBlank() || expiryDatemin == null)) {
return cb.lessThanOrEqualTo(root.get("expiryDate"), LocalDate.parse(expiryDatemax));
} else {
return cb.between(root.get("expiryDate"), LocalDate.parse(expiryDatemin),
LocalDate.parse(expiryDatemax));
}
};}
public static Specification<Product> withPrices(String pricelow, String pricemax) {
return (root, query, cb) -> {
if ((pricelow.isBlank() || pricelow == null) && (pricemax.isBlank() || pricemax == null)) {
return cb.conjunction();
} else if ((pricemax.isBlank() || pricemax == null)) {
return cb.greaterThanOrEqualTo(root.get("price"), Double.valueOf(pricelow));
} else if ((pricelow.isBlank() || pricelow == null)) {
return cb.lessThanOrEqualTo(root.get("price"), Double.valueOf(pricemax));
} else {
return cb.between(root.get("price"), Double.valueOf(pricelow), Double.valueOf(pricemax));
}
};}
public static Specification<Product> withQuantity(String quantitymin, String quantitymax) {
return (root, query, cb) -> {
if ((quantitymin.isBlank() || quantitymin == null) && (quantitymax.isBlank() || quantitymax == null)) {
return cb.conjunction();
} else if ((quantitymax.isBlank() || quantitymax == null)) {
return cb.greaterThanOrEqualTo(root.get("quantity"), Integer.valueOf(quantitymin));
} else if ((quantitymin.isBlank() || quantitymin == null)) {
return cb.lessThanOrEqualTo(root.get("quantity"), Integer.valueOf(quantitymax));
} else {
return cb.between(root.get("quantity"), Integer.valueOf(quantitymin), Integer.valueOf(quantitymax));
}
};
}
public static Specification<Product> withType(String type) {
return (root, query, cb) -> {
if (type == null) {
return cb.conjunction();
} else
return cb.like(root.get("type"), type);
};
}
public static Specification<Product> withname(String name) {
return (root, query, cb) -> {
if (name == null) {
return cb.conjunction();
} else
return cb.like(root.get("name"), name);
};
}
public static Specification<Product> withcompany(String company) {
return (root, query, cb) -> {
if (company == null) {
return cb.conjunction();
} else
return cb.like(root.get("company"), company);
};
}
如有任何帮助,我们将不胜感激。我对 Spring/Spring 引导很陌生,规格 API 对我来说很陌生。
我做了以下更改,对我来说效果很好。
将return cb.conjunction();
替换为return null;
规格 class.
从规范中删除 .isBlank()
检查
Class.
添加.and(ProductSpecifications.withName(name))
进行筛选
服务中的产品方法 class。
将 required=false
添加到您所有的 @RequestParam @RequestParam(required=false)
我正在使用动态查询为我的 API 演示项目开发 filter/Search 端点。 这是我的过滤器端点。
@GetMapping("/filter")
public ResponseEntity<List<ProductDto>> filterProducts(@RequestParam("name") String name,
@RequestParam("expiryDatemin") String expiryDatemin, @RequestParam("expiryDatemax") String expiryDatemax,
@RequestParam("type") String type, @RequestParam("quantitymin") String quantityin,
@RequestParam("quantitymin") String quantitymax, @RequestParam("company") String company,
@RequestParam("pricemin") String pricemin, @RequestParam("pricemax") String pricemax) {
return new ResponseEntity<List<ProductDto>>(productgetservice.filterProducts(expiryDatemin, expiryDatemax, name,
type, quantityin, quantitymax, company, pricemin, pricemax), HttpStatus.OK);
}
我想做的是用户可以输入任何元素,并且只显示满足过滤器的数据。
如果用户将所有值都发送为 null 或空,则它应该 return table 的完整数据。
就像在末尾具有最小最大值的变量一样,是在这些间隔之间获取数据。
如果仅输入最小值,则应发送高于该条件的所有数据;如果仅输入最大值,则应显示低于该条件的所有数据。
我的 serviceImpl class 方法如下:
@Override
public List<ProductDto> filterProducts(String expiryDatemin, String expiryDatemax, String name, String type,
String quantitymin, String quantitymax, String company, String pricemin, String pricemax) {
List<Product> products = productrepository.findAll(where(ProductSpecifications
.withExpiryDates(expiryDatemin, expiryDatemax).and(ProductSpecifications.withcompany(company))
.and(ProductSpecifications.withPrices(pricemin, pricemax))
.and(ProductSpecifications.withQuantity(quantitymin, quantitymax))
.and(ProductSpecifications.withType(type))));
return productsListToProductDto(products);
}
我遇到的问题是,当我使用 'and' 发送数据时,它总是 return 一个空数组作为有效负载。 当我用 'or' 替换 and 时,它 returns table 的全部数据作为列表。
这是我的产品规格 class 方法:
public static Specification<Product> withExpiryDates(String expiryDatemin, String expiryDatemax) {
return (root, query, cb) -> {
if ((expiryDatemax.isBlank() || expiryDatemax == null)
&& (expiryDatemin.isBlank() || expiryDatemin == null)) {
return cb.conjunction();
} else if ((expiryDatemax.isBlank() || expiryDatemax == null)) {
return cb.greaterThanOrEqualTo(root.get("expiryDate"), LocalDate.parse(expiryDatemin));
} else if ((expiryDatemin.isBlank() || expiryDatemin == null)) {
return cb.lessThanOrEqualTo(root.get("expiryDate"), LocalDate.parse(expiryDatemax));
} else {
return cb.between(root.get("expiryDate"), LocalDate.parse(expiryDatemin),
LocalDate.parse(expiryDatemax));
}
};}
public static Specification<Product> withPrices(String pricelow, String pricemax) {
return (root, query, cb) -> {
if ((pricelow.isBlank() || pricelow == null) && (pricemax.isBlank() || pricemax == null)) {
return cb.conjunction();
} else if ((pricemax.isBlank() || pricemax == null)) {
return cb.greaterThanOrEqualTo(root.get("price"), Double.valueOf(pricelow));
} else if ((pricelow.isBlank() || pricelow == null)) {
return cb.lessThanOrEqualTo(root.get("price"), Double.valueOf(pricemax));
} else {
return cb.between(root.get("price"), Double.valueOf(pricelow), Double.valueOf(pricemax));
}
};}
public static Specification<Product> withQuantity(String quantitymin, String quantitymax) {
return (root, query, cb) -> {
if ((quantitymin.isBlank() || quantitymin == null) && (quantitymax.isBlank() || quantitymax == null)) {
return cb.conjunction();
} else if ((quantitymax.isBlank() || quantitymax == null)) {
return cb.greaterThanOrEqualTo(root.get("quantity"), Integer.valueOf(quantitymin));
} else if ((quantitymin.isBlank() || quantitymin == null)) {
return cb.lessThanOrEqualTo(root.get("quantity"), Integer.valueOf(quantitymax));
} else {
return cb.between(root.get("quantity"), Integer.valueOf(quantitymin), Integer.valueOf(quantitymax));
}
};
}
public static Specification<Product> withType(String type) {
return (root, query, cb) -> {
if (type == null) {
return cb.conjunction();
} else
return cb.like(root.get("type"), type);
};
}
public static Specification<Product> withname(String name) {
return (root, query, cb) -> {
if (name == null) {
return cb.conjunction();
} else
return cb.like(root.get("name"), name);
};
}
public static Specification<Product> withcompany(String company) {
return (root, query, cb) -> {
if (company == null) {
return cb.conjunction();
} else
return cb.like(root.get("company"), company);
};
}
如有任何帮助,我们将不胜感激。我对 Spring/Spring 引导很陌生,规格 API 对我来说很陌生。
我做了以下更改,对我来说效果很好。
将
return cb.conjunction();
替换为return null;
规格 class.从规范中删除
.isBlank()
检查 Class.添加
.and(ProductSpecifications.withName(name))
进行筛选 服务中的产品方法 class。将
required=false
添加到您所有的@RequestParam @RequestParam(required=false)