matrixVariable允许我们非常方便地进行多条件组合查询!这里我以商品查询为例,详细介绍matrixVariable的使用。
我们经常有如下需求:查询一定价格区间的商品;查询某些类别的商品;查询某些生产者的商品……第一反应你是不是想到了使用pojo封装查询条件,然后快速完成查询功能?抱歉,这里你看不到我用pojo的实现。但你可以试着看看使用SpringMVC的matrixVariable是怎么实现的。
先看看查询的展示结果:
1.没有使用查询条件查询结果:
下面分个讲解条件查询……
按照类别,价格区间,生产者查询,其实最后一个查询条件使用@RequestParam
,类别使用@PathVariable
,真正使用到matrixVariable
的是 价格区间。
Controller层代码:
@RequestMapping("/{category}/{ByCriteria}")
public String filterProducts(
@PathVariable("category") String category,
@MatrixVariable(pathVar="ByCriteria") Map<String, List<String>> filterParams,
@RequestParam("manufacturer") String manufacturer, Model model) {
model.addAttribute("products", productService.getProductsByCriteria(category, filterParams, manufacturer));
return "products";
}
Service层代码:
public Set<Product> getProductsByCriteria(String category, Map<String, List<String>> filterParams, String manufacturer) {
return productRepository.getProductsByCriteria(category, filterParams, manufacturer);
}
Dao层代码:
public Set getProductsByCriteria(String category, Map<String, List<String>> filterParams, String manufacturer) {
Set productsByPrice = new HashSet();
Set productsByManufacturer = new HashSet();
Set productsByCategory = new HashSet(getProductByCategory(category));
Set<String> criterias = filterParams.keySet();
if(criterias.contains("low")) {
for(String lowPrice : filterParams.get("low")) {
productsByPrice = getByPrice(lowPrice, ">");
}
}
if(criterias.contains("high")) {
for(String highPrice : filterParams.get("high")) {
productsByPrice.retainAll(getByPrice(highPrice, "<"));
}
}
productsByManufacturer = new HashSet(getProductsByManufacturer(manufacturer));
productsByCategory.retainAll(productsByPrice);
productsByPrice.retainAll(productsByManufacturer);
return productsByCategory;
}
public List getProductByCategory(String category) {
List productsByCategory = new ArrayList();
for(Product product : listOfProducts) {
if(category.equalsIgnoreCase(product.getCategory())) {
productsByCategory.add(product);
}
}
return productsByCategory;
}
private Set<Product> getByPrice(String price, String signal) {
Set<Product> productByPrice = new HashSet<Product>();
BigDecimal decimalPrice = new BigDecimal(price);
if(signal.equals("<")) {
for(Product product : listOfProducts) {
if(product.getUnitPrice().compareTo(decimalPrice)<0) {
productByPrice.add(product);
}
}
}
else if(signal.equals(">")) {
for(Product product : listOfProducts) {
if(product.getUnitPrice().compareTo(decimalPrice)>0) {
productByPrice.add(product);
}
}
}
return productByPrice;
}
public List getProductsByManufacturer(String manufacturer) {
List productsByManufactures = new ArrayList();
for(Product product : listOfProducts) {
if(manufacturer.equalsIgnoreCase(product.getManufacturer())) {
productsByManufactures.add(product);
}
}
return productsByManufactures;
}
SpringMVC配置文件中配置如下:
<mvc:annotation-driven enable-matrix-variables="true"/>
一切OK!
根据 品牌,类别查询代码如下:
@RequestMapping("/filter/{ByCriteria}")
public String getProductsByFilter(@MatrixVariable(pathVar="ByCriteria")
Map<String, List<String>> filterParams, Model model) {
model.addAttribute("products", productService.getProductsByFilter(filterParams));
return "products";
}
public Set<Product> getProductsByFilter(Map<String, List<String>> filterParams) {
return productRepository.getProductsByFilter(filterParams);
}
public Set getProductsByFilter(Map<String, List<String>> filterParams) {
Set productsByBrand = new HashSet();
Set productsByCategory = new HashSet();
Set<String> criterias = filterParams.keySet();
if(criterias.contains("brand")) {
for(String brandName : filterParams.get("brand")) {
for(Product product : listOfProducts) {
if(brandName.equalsIgnoreCase(product.getManufacturer())) {
productsByBrand.add(product);
}
}
}
}
if(criterias.contains("category")) {
for(String category : filterParams.get("category")) {
productsByCategory.addAll(this.getProductByCategory(category));
}
}
productsByCategory.retainAll(productsByBrand);
return productsByCategory;
}
完成!