jqGrid与Struts2的结合应用(五) —— 结合Action类进行数据查询

本文详细介绍了jqGrid的查找功能,包括工具条查询、单条件表单查询、高级表单查询和自定义查询,并提供了相应的代码实现。重点解释了如何通过服务器端的JqGridBaseAction类和客户端的searchGrid方法实现复杂条件查询。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这篇主要讲的是jqGrid的查找功能。

根据官方文档的介绍,jqGrid的查找功能分四种:

  • 工具条查询;
  • 自定义查询;
  • 单条件表单查询;
  • 高级表单查询(复杂条件查询);


我个人认为这样划分比较复杂,可以基本分为两大类,即:
表单查询:包括单条件查询和高级查询(复杂条件查询);
工具条查询:包括工具条查询和自定义查询;

而这两大类中,也以表单查询更常用。

现在逐个说明一下(我改变了官方文档的讲解顺序,我觉得自己的这个顺序,更直观,更靠近现实使用)。


1. 单条件表单查询

先从服务器端看起,为了配合jqGrid的查询功能,我们需要在JqGridBaseAction类中添加几个成员变量。成员变量的名字必须和jqGrid的prmNames选项中定义的参数名相对应上(具体参考本系列文章的第一篇)。

改进后的JqGridBaseAction类代码:

  1. package cn.gengv.struts2ex.jqGrid; 
  2.   
  3. import java.util.ArrayList; 
  4. import java.util.Collections; 
  5. import java.util.List; 
  6.   
  7. import com.byzl.hare.dao.impl.Criterion; 
  8. import com.byzl.hare.dao.impl.Criterion.CompareType; 
  9. import com.opensymphony.xwork2.ActionSupport; 
  10.   
  11. @SuppressWarnings("serial"
  12. public abstract class JqGridBaseAction<T> extends ActionSupport { 
  13.     private List<T> gridModel = Collections.emptyList(); 
  14.     private Integer rows = 0
  15.     private Integer page = 0
  16.     private Integer total = 0
  17.     private Integer record = 0
  18.     private String sord; 
  19.     private String sidx; 
  20.       
  21.     // (1)添加和查询有关的成员变量search、searchField、searchString、searchOper 
  22.     private boolean search; 
  23.     private String searchField; 
  24.     private String searchString; 
  25.     private String searchOper; 
  26.   
  27.     public abstract int getResultSize(); 
  28.     public abstract List<T> listResults(int from, int length); 
  29.       
  30.     // (2)添加用于根据条件进行查询的方法 
  31.     public abstract int getResultSize(List<Criterion> criteria); 
  32.     public abstract List<T> listResults(List<Criterion> criteria, int from, int length); 
  33.   
  34.     public String refreshGridModel() { 
  35.         try
  36.             List<Criterion> criteria = Collections.emptyList(); 
  37.               
  38.             // (3)如果search值为true,则表明是查询请求 
  39.             if(search == true) { 
  40.                   
  41.                 // (4)通过searchField、searchString、searchOper生成通用的查询条件 
  42.                 Criterion criterion = this.generateSearchCriterion(searchField, searchString, searchOper); 
  43.              
  44.                 criteria = new ArrayList<Criterion>(); 
  45.                  
  46.                 if(criterion != null) { 
  47.                     criteria.add(criterion); 
  48.                 } 
  49.             } 
  50.               
  51.             int from = rows * (page - 1); 
  52.             int length = rows; 
  53.               
  54.             List<T> results = Collections.emptyList(); 
  55.               
  56.             if(!criteria.isEmpty()) {   // (5)如果criteria列表不为空,则根据条件进行查询 
  57.                 record = this.getResultSize(criteria); 
  58.                 results = this.listResults(criteria, from, length); 
  59.                  
  60.             } else
  61.                 record = this.getResultSize(); 
  62.                 results = this.listResults(from, length); 
  63.                  
  64.             } 
  65.               
  66.             this.setGridModel(results); 
  67.             total = (int) Math.ceil((double) record / (double) rows); 
  68.             return SUCCESS; 
  69.         } catch (Exception e) { 
  70.             e.printStackTrace(); 
  71.             this.addActionError(e.getMessage()); 
  72.             return ERROR; 
  73.         } 
  74.     } 
  75.      
  76.     // (6)通过searchField、searchString、searchOper三个参数生成Criterion的方法 
  77.     public Criterion generateSearchCriterion(String searchField, 
  78.             String searchString, String searchOper) { 
  79.         Criterion criterion = null
  80.          
  81.         // (7)如果searchField、searchString、searchOper均不为null,且searchString不为空字符串时,则创建Criterion 
  82.         if (searchField != null && searchString != null 
  83.                 & searchString.length() > 0 && searchOper != null) { 
  84.             if ("eq".equals(searchOper)) { 
  85.                 criterion = Criterion.getEqualCriterion(searchField, 
  86.                         searchString, null); 
  87.             } else if ("ne".equals(searchOper)) { 
  88.                 criterion = Criterion.getCompareCriterion(CompareType.NE, 
  89.                         searchField, searchString, null); 
  90.             } else if ("lt".equals(searchOper)) { 
  91.                 criterion = Criterion.getCompareCriterion(CompareType.LT, 
  92.                         searchField, searchString, null); 
  93.             } else if ("le".equals(searchOper)) { 
  94.                 criterion = Criterion.getCompareCriterion(CompareType.LTE, 
  95.                         searchField, searchString, null); 
  96.             } else if ("gt".equals(searchOper)) { 
  97.                 criterion = Criterion.getCompareCriterion(CompareType.GT, 
  98.                         searchField, searchString, null); 
  99.             } else if ("ge".equals(searchOper)) { 
  100.                 criterion = Criterion.getCompareCriterion(CompareType.GTE, 
  101.                         searchField, searchString, null); 
  102.             } else if ("bw".equals(searchOper)) { 
  103.                 criterion = Criterion.getLikeCriterion(searchField, 
  104.                         searchString + "%", null); 
  105.             } else if ("bn".equals(searchOper)) { 
  106.                 criterion = Criterion.getNotLikeCriterion(searchField, 
  107.                         searchString + "%", null); 
  108.             } else if ("ew".equals(searchOper)) { 
  109.                 criterion = Criterion.getLikeCriterion(searchField, "%" 
  110.                         + searchString, null); 
  111.             } else if ("en".equals(searchOper)) { 
  112.                 criterion = Criterion.getNotLikeCriterion(searchField, "%" 
  113.                         + searchString, null); 
  114.             } else if ("cn".equals(searchOper)) { 
  115.                 criterion = Criterion.getLikeCriterion(searchField, "%" 
  116.                         + searchString + "%", null); 
  117.             } else if ("nc".equals(searchOper)) { 
  118.                 criterion = Criterion.getNotLikeCriterion(searchField, "%" 
  119.                         + searchString + "%", null); 
  120.             } 
  121.         } 
  122.         return criterion; 
  123.     } 
  124.      
  125.     // getter和setter 
  126.     ... 

说明:

  • (1)处添加了关于查询使用到的成员变量,这些成员变量会接收从客户端jqGrid传来的参数,这些参数的名称都是由jqGrid的prmNames选项定义的;
  • (2)处添加了两个方法,用于根据条件列表,进行数据记录查询;(关于条件列表List<Criterion>稍后介绍);
  • (3)处判断成员变量search的值,如果是查询请求,jqGrid会发送search值为true的请求;
  • (4)(6)(7)通过searchField、searchString、searchOper三个参数生成Criterion的方法;以前在学习Hibernate的时候,里面就介绍过使用Criterion的方式;有的朋友对Hibernate奉若神明,但我一直对Hibernate的灵活度不太满意;不过这种将查询条件抽象出来的思路还是值得借鉴的。因此,我虽然后台使用的是Spring的JdbcTemplate,但为了抽象化Dao内的操作,我自己写了一个Criterion类(具体代码在后面)。使用这个Criterion列表来简化查询条件在各个层的传递。
  • (5)如果条件列表不为空,则调用新加入的条件查询方法。

Criterion类的代码:

  1. package com.byzl.hare.dao.impl; 
  2. import java.util.ArrayList; 
  3. import java.util.Collections; 
  4. import java.util.List; 
  5. public class Criterion { 
  6.     public static enum CriterionType { 
  7.         EQUAL, LIKE, COMPARE, NOT_LIKE 
  8.     } 
  9.     public static enum CompareType { 
  10.         GT, GTE, LT, LTE, EQ, NE 
  11.     } 
  12.     private CriterionType criterionType; 
  13.     private String tableName; 
  14.     private String field; 
  15.     private Object value; 
  16.     // 将Criteria转换为SQL条件语句 
  17.     public static String convertToSql(List<Criterion> criteria) { 
  18.         String criteriaString = ""
  19.         StringBuilder sb = new StringBuilder(); 
  20.         for (Criterion criterion : criteria) { 
  21.             String prefix = criterion.getFieldPrefix(); 
  22.             switch (criterion.getCriterionType()) { 
  23.             case EQUAL: 
  24.                 sb.append(prefix + criterion.getField() + "=? and "); 
  25.                 break
  26.             case LIKE: 
  27.                 sb.append(prefix + criterion.getField() + " like ? and "); 
  28.                 break
  29.                  
  30.             case NOT_LIKE: 
  31.                 sb.append(prefix + criterion.getField() + " not like ? and "); 
  32.                 break
  33.             case COMPARE: 
  34.                 CompareType compareType = ((CompareCriterion) criterion) 
  35.                         .getCompareType(); 
  36.                 switch (compareType) { 
  37.                 case EQ: 
  38.                     sb.append(prefix + criterion.getField() + "=? and "); 
  39.                     break
  40.                 case NE: 
  41.                     sb.append(prefix + criterion.getField() + "<>? and "); 
  42.                     break
  43.                 case GT: 
  44.                     sb.append(prefix + criterion.getField() + ">? and "); 
  45.                     break
  46.                 case GTE: 
  47.                     sb.append(prefix + criterion.getField() + ">=? and "); 
  48.                     break
  49.                 case LT: 
  50.                     sb.append(prefix + criterion.getField() + "<? and "); 
  51.                     break
  52.                 case LTE: 
  53.                     sb.append(prefix + criterion.getField() + "<=? and "); 
  54.                     break
  55.                 } 
  56.                 break
  57.             } 
  58.         } 
  59.         int i = -1
  60.         if ((i = sb.lastIndexOf(" and ")) != -1) { 
  61.             criteriaString = sb.substring(0, i); 
  62.         } 
  63.         return criteriaString; 
  64.     } 
  65.     // 将Criteria各条件的值转换为List<Object> 
  66.     public static List<Object> getCriteriaValues(List<Criterion> criteria) { 
  67.         List<Object> criteriaValues = criteria.isEmpty() ? Collections 
  68.                 .emptyList() : new ArrayList<Object>(); 
  69.         for (Criterion criterion : criteria) { 
  70.             criteriaValues.add(criterion.getValue()); 
  71.         } 
  72.         return criteriaValues; 
  73.     } 
  74.     public CriterionType getCriterionType() { 
  75.         return criterionType; 
  76.     } 
  77.     public void setCriterionType(CriterionType criterionType) { 
  78.         this.criterionType = criterionType; 
  79.     } 
  80.     public String getField() { 
  81.         return field; 
  82.     } 
  83.     public void setField(String field) { 
  84.         this.field = field; 
  85.     } 
  86.     public Object getValue() { 
  87.         return value; 
  88.     } 
  89.     public void setValue(Object value) { 
  90.         this.value = value; 
  91.     } 
  92.     public static Criterion getCompareCriterion(CompareType compareType, 
  93.             String field, Object value, String tableName) { 
  94.         CompareCriterion compareCriterion = new CompareCriterion(); 
  95.         compareCriterion.setCriterionType(CriterionType.COMPARE); 
  96.         compareCriterion.setCompareType(compareType); 
  97.         compareCriterion.setField(field); 
  98.         compareCriterion.setValue(value); 
  99.         compareCriterion.setTableName(tableName); 
  100.         return compareCriterion; 
  101.     } 
  102.     public static Criterion getLikeCriterion(String field, Object value, 
  103.             String tableName) { 
  104.         LikeCriterion likeCriterion = new LikeCriterion(); 
  105.         likeCriterion.setCriterionType(CriterionType.LIKE); 
  106.         likeCriterion.setField(field); 
  107.         likeCriterion.setValue(value); 
  108.         likeCriterion.setTableName(tableName); 
  109.         return likeCriterion; 
  110.     } 
  111.      
  112.     public static Criterion getNotLikeCriterion(String field, Object value, 
  113.             String tableName) { 
  114.         NotLikeCriterion notLikeCriterion = new NotLikeCriterion(); 
  115.         notLikeCriterion.setCriterionType(CriterionType.NOT_LIKE); 
  116.         notLikeCriterion.setField(field); 
  117.         notLikeCriterion.setValue(value); 
  118.         notLikeCriterion.setTableName(tableName); 
  119.         return notLikeCriterion; 
  120.     } 
  121.     public static Criterion getEqualCriterion(String field, Object value, 
  122.             String tableName) { 
  123.         EqualCriterion equalCriterion = new EqualCriterion(); 
  124.         equalCriterion.setCriterionType(CriterionType.EQUAL); 
  125.         equalCriterion.setField(field); 
  126.         equalCriterion.setValue(value); 
  127.         equalCriterion.setTableName(tableName); 
  128.         return equalCriterion; 
  129.     } 
  130.     public static class LikeCriterion extends Criterion { 
  131.     } 
  132.      
  133.     public static class NotLikeCriterion extends Criterion { 
  134.     } 
  135.     public static class EqualCriterion extends Criterion { 
  136.     } 
  137.     public static class CompareCriterion extends Criterion { 
  138.         private CompareType compareType; 
  139.         public CompareType getCompareType() { 
  140.             return compareType; 
  141.         } 
  142.         public void setCompareType(CompareType compareType) { 
  143.             this.compareType = compareType; 
  144.         } 
  145.     } 
  146.     public String getTableName() { 
  147.         return tableName; 
  148.     } 
  149.     public void setTableName(String tableName) { 
  150.         this.tableName = tableName; 
  151.     } 
  152.     public String getFieldPrefix() { 
  153.         return (tableName == null || tableName.length() == 0) ? "" : tableName 
  154.                 + "."
  155.     } 

简要说明一下:

  • 我把Criterion分成4类:EqualCriterion、CompareCriterion、LikeCriterion、NotLikeCriterion。(具体划分方式全为使用方便)
  • 另外还有两个静态方法:convertToSql和getCriteriaValues,用来将Criterion列表转化为JdbcTemplate需要的SQL子句和参数列表。


回到ListContactsAction,代码如下:

  1. package cn.gengv.struts2ex.jqGrid; 
  2.   
  3. import java.util.Collections; 
  4. import java.util.List; 
  5. import com.byzl.hare.dao.impl.Criterion; 
  6. import com.byzl.hare.model.Contact; 
  7. import com.byzl.hare.service.ContactService; 
  8.   
  9. @SuppressWarnings("serial"
  10. public class ListContactsAction extends JqGridBaseAction<Contact> { 
  11.      
  12.     private ContactService contactService; 
  13.      
  14.     @Override 
  15.     public String execute() { 
  16.         return this.refreshGridModel(); 
  17.     } 
  18.      
  19.     @Override 
  20.     public int getResultSize() { 
  21.         return this.contactService.queryResultsCount(null); 
  22.     } 
  23.     @Override 
  24.     public List<Contact> listResults(int from, int length) { 
  25.         return this.contactService.queryByPage(null, from, length); 
  26.     } 
  27.      
  28.     @Override 
  29.     public int getResultSize(List<Criterion> criteria) { 
  30.         return this.contactService.queryResultsCount(criteria); 
  31.     } 
  32.      
  33.     @Override 
  34.     public List<Contact> listResults(List<Criterion> criteria, int from, int length) { 
  35.         List<Contact> results = Collections.emptyList(); 
  36.          
  37.         results = this.contactService.queryByPage(criteria, from, length); 
  38.          
  39.         return results; 
  40.     } 
  41.   
  42.     public void setContactService(ContactService contactService) { 
  43.         this.contactService = contactService; 
  44.     } 

OK,服务器端的工作就先这样了,应对单条件查询已经足够了。再来看看客户端需要什么特别的。

jqGrid的单条件查询和高级查询(复杂条件查询)都是基于表单的查询,使用的都是jqGrid的searchGrid方法:
    $("#grid_id").searchGrid( options );
或者
    $("#grid_id").jqGrid('searchGrid', options );
   
注:要想使用searchGrid方法,在下载jqGrid的时候,必须包含Common, Form Edit, Search Plugin的模块。

在Navigator按钮栏中的查询按钮,默认就是调用这个方法。



searchGrid也有很多选项,在language文件(grid.locale-xx.js)中,有关于这些选项的默认值定义。下面介绍一下主要常用的选项:

  • afterShowSearch :用于定义每次查询对话框显示之后,要执行的事件函数;
  • beforeShowSearch :用于定义每次查询对话框显示之前,要执行的事件函数;
  • caption :查询对话框的标题;
  • closeAfterSearch :如果设为true,则每次在查询对话框中点击“查询”按钮完成查询后,对话框都会被关闭;默认为false;
  • closeAfterReset :如果设为true,则每次在查询对话框中点击“重置”按钮完成查询后,对话框都会被关闭;默认为false;
  • closeOnEscape :如果设为true,则当按ESC键的时候,对话框会被关闭;默认为false;
  • Find :查询对话框里“查询”按钮上的文本;
  • Reset :查询对话框里“重置”按钮上的文本;
  • sopt :用来设置通用的查询规则,如['eq','ne','lt','le','gt','ge','bw','bn','in','ni','ew','en','cn','nc'];如果为设置,则使用全部规则;
  • odata :用来翻译sopt中规则的对应数组;
  • onClose :当查询对话框关闭时,将要执行的事件函数。可以返回true或false;如果返回false,则查询对话框不会被关闭。
  • onInitializeSearch :当查询对话框创建时,将要执行的事件函数。
  • recreateFilter :如果设置为true,则当动态改变colModel的属性时,重建查询并解除时间绑定。
  • sField, sOper, sValue :当提交查询请求时,对应着所包含的有关于查询的参数;默认值分别是'searchField','searchOper','searchString'。

以上这些就是关于单条件查询的选项;关于复杂条件查询的选项稍后介绍。

注意:在searchGrid方法中设定这些选项,和在navGrid方法的prmSearch参数中设置这些选项(参见上一篇),作用效果是相同的。

[javascript] view plain copy
  1. var singleCriterionSearch = function() { 
  2.     $("#gridTable").jqGrid("searchGrid", { 
  3.         caption: "查找"
  4.         Find: "Go!"
  5.         closeAfterSearch: true 
  6.     }); 
  7. }; 

等同于

[javascript] view plain copy
  1. $("#gridTable").jqGrid("navGrid", "#gridPager", {},{},{},{}, 
  2.     {   // 与查询相关的prmSearch参数 
  3.         caption: "查找"
  4.         Find: "Go!"
  5.         closeAfterSearch: true 
  6.     },{}); 

当点击查询对话框中的“查询”按钮的时候,jqGrid会向Server提交一个请求,例如:
http://localhost:8085/Hare/jqGridTest/jqGrid05.action?search=true&nd=1278685481936&rows=15&page=1&sidx=&sord=asc&searchField=id&searchString=9000&searchOper=ge

2. 高级查询(复杂条件表单查询)

在上一部分已经提到了,单条件表单查询和高级查询(复杂条件表单查询)都是用的是searchGrid方法,只不过是传入的选项值有所不同而已。其中最重要的一个选项就是multipleSearch。

下面就来详细介绍在searchGrid中,与复杂条件查询相关的主要选项:

  • multipleSearch :如果设置为true,则激活复杂条件查询;默认为false。
  • groupOps :默认通常为[ { op: "AND", text: "all" }, { op: "OR", text: "any" } ],表示需要满足多重条件的方式,例如满足所有查询条件或者满足任意查询条件。
  • sFilter :对应着在复杂查询提交请求时,对应的参数名;默认为filters。

将javascript代码改为:

[javascript] view plain copy
  1. $("#gridTable").jqGrid("navGrid", "#gridPager", {},{},{},{}, 
  2.     {   // 与查询相关的prmSearch参数 
  3.         caption: "查找"
  4.         Find: "Go!"
  5.         closeAfterSearch: true
  6.         multipleSearch: true
  7.         groupOps: [{ op: "AND", text: "全部" }] 
  8.     },{}); 

或者

[javascript] view plain copy
  1. var complexCriteriaSearch = function() { 
  2.     $("#gridTable").jqGrid("searchGrid", { 
  3.         caption: "查找"
  4.         Find: "Go!"
  5.         closeAfterSearch: true
  6.         multipleSearch: true
  7.         groupOps: [{ op: "AND", text: "全部" }] 
  8.     }); 
  9. }; 

除了选项上的不同以外,客户端的另一个不同之处在于,向Server端传递的参数不同。在第一部分的例子中可以看到,当单条件查询提交请求的时候,传递的参数是:
http://localhost:8085/Hare/jqGridTest/jqGrid05.action?search=true&nd=1278685481936&rows=15&page=1&sidx=&sord=asc&searchField=id&searchString=9000&searchOper=ge

即:

[javascript] view plain copy
  1. nd: 1278688214496 
  2. page:   1 
  3. rows:   15 
  4. search: true 
  5. searchField:    id 
  6. searchOper: ge 
  7. searchString:   9000 
  8. sidx:    
  9. sord:   asc 

而复杂条件的查询的参数是下面这种形式:
http://localhost:8085/Hare/jqGridTest/jqGrid05.action?search=true&nd=1278688110637&rows=15&page=1&sidx=&sord=asc&filters=%7B%22groupOp%22%3A%22AND%22%2C%22rules%22%3A%5B%7B%22field%22%3A%22id%22%2C%22op%22%3A%22le%22%2C%22data%22%3A%221500%22%7D%2C%7B%22field%22%3A%22lastName%22%2C%22op%22%3A%22bw%22%2C%22data%22%3A%22LN-3%22%7D%2C%7B%22field%22%3A%22email%22%2C%22op%22%3A%22cn%22%2C%22data%22%3A%22sy%22%7D%5D%7D

即:

[javascript] view plain copy
  1. filters:    {"groupOp":"AND","rules":[{"field":"id","op":"le","data":"1500"},{"field":"lastName","op":"bw","data":"LN-3"},{"field":"email","op":"cn","data":"sy"}]} 
  2. nd: 1278688110637 
  3. page:   1 
  4. rows:   15 
  5. search: true 
  6. sidx:    
  7. sord:   asc 

我们可以发现,传递的参数中除了search以外,searchField、searchOper、searchString都不见了,取而代之的是一个filters参数。filters参数查询条件以及复杂条件的匹配方式封装成了json的格式,然后传递给Server。

针对这种格式的参数,继续使用第一个例子中的JqGridBaseAction类的查询方式,显然是无法应对的。我们必须再次改进JqGridBaseAction类。而关键之处就是如何解析这个json格式的filters参数。

为此,我引入了json-lib库(http://json-lib.sourceforge.net/ ),其他的关于json的java库还可以访问http://www.json.org/

在JqGridBaseAction类中添加方法generateSearchCriteriaFromFilters(),来将filters参数解析为Criterion列表。

  1. public List<Criterion> generateSearchCriteriaFromFilters(String filters) { 
  2.     List<Criterion> criteria = new ArrayList<Criterion>(); 
  3.      
  4.     JSONObject jsonObject = JSONObject.fromObject(filters); 
  5.      
  6.     JSONArray rules = jsonObject.getJSONArray("rules"); 
  7.      
  8.     for(Object obj : rules) { 
  9.         JSONObject rule = (JSONObject) obj; 
  10.          
  11.         String field = rule.getString("field"); 
  12.         String op = rule.getString("op"); 
  13.         String data = rule.getString("data"); 
  14.          
  15.         Criterion criterion = this.generateSearchCriterion(field, data, op); 
  16.          
  17.         if(criterion != null) { 
  18.             criteria.add(criterion); 
  19.         } 
  20.     } 
  21.      
  22.     return criteria; 

其余部分的代码:

  1. package cn.gengv.struts2ex.jqGrid; 
  2.   
  3. import java.util.ArrayList; 
  4. import java.util.Collections; 
  5. import java.util.List; 
  6. import net.sf.json.JSONArray; 
  7. import net.sf.json.JSONObject; 
  8.   
  9. import com.byzl.hare.dao.impl.Criterion; 
  10. import com.byzl.hare.dao.impl.Criterion.CompareType; 
  11. import com.opensymphony.xwork2.ActionSupport; 
  12.   
  13. @SuppressWarnings("serial"
  14. public abstract class JqGridBaseAction<T> extends ActionSupport { 
  15.     private List<T> gridModel = Collections.emptyList(); 
  16.     private Integer rows = 0
  17.     private Integer page = 0
  18.     private Integer total = 0
  19.     private Integer record = 0
  20.     private String sord; 
  21.     private String sidx; 
  22.       
  23.     private boolean search; 
  24.     private String searchField; 
  25.     private String searchString; 
  26.     private String searchOper; 
  27.   
  28.     public abstract int getResultSize(); 
  29.     public abstract List<T> listResults(int from, int length); 
  30.      
  31.     // (1)添加filters成员变量 
  32.     private String filters; 
  33.       
  34.     public abstract int getResultSize(List<Criterion> criteria); 
  35.     public abstract List<T> listResults(List<Criterion> criteria, int from, int length); 
  36.      
  37.     public String refreshGridModel() { 
  38.         try
  39.             List<Criterion> criteria = Collections.emptyList(); 
  40.               
  41.             if(search == true) { 
  42.                 criteria = new ArrayList<Criterion>(); 
  43.                  
  44.                 // (2)将Filter转化为Criterion列表,并加入总的Criterion列表 
  45.                 if(filters != null && filters.length()>0) { 
  46.                     criteria.addAll(this.generateSearchCriteriaFromFilters(filters)); 
  47.                 } 
  48.                   
  49.                 // (3)将searchField、searchString、searchOper转化为Criterion,并加入总的Criterion列表 
  50.                 Criterion criterion = this.generateSearchCriterion(searchField, searchString, searchOper); 
  51.                 if(criterion != null) { 
  52.                     criteria.add(criterion); 
  53.                 } 
  54.             } 
  55.               
  56.             int from = rows * (page - 1); 
  57.             int length = rows; 
  58.               
  59.             List<T> results = Collections.emptyList(); 
  60.               
  61.             if(!criteria.isEmpty()) { 
  62.                 record = this.getResultSize(criteria); 
  63.                 results = this.listResults(criteria, from, length); 
  64.                  
  65.             } else
  66.                 record = this.getResultSize(); 
  67.                 results = this.listResults(from, length); 
  68.                  
  69.             } 
  70.               
  71.             this.setGridModel(results); 
  72.             total = (int) Math.ceil((double) record / (double) rows); 
  73.             return SUCCESS; 
  74.         } catch (Exception e) { 
  75.             e.printStackTrace(); 
  76.             this.addActionError(e.getMessage()); 
  77.             return ERROR; 
  78.         } 
  79.     } 
  80.       
  81.       
  82.     public Criterion generateSearchCriterion(String searchField, 
  83.             String searchString, String searchOper) { 
  84.         ... 
  85.          
  86.     } 
  87.      
  88.     public List<Criterion> generateSearchCriteriaFromFilters(String filters) { 
  89.         List<Criterion> criteria = new ArrayList<Criterion>(); 
  90.          
  91.         JSONObject jsonObject = JSONObject.fromObject(filters); 
  92.          
  93.         JSONArray rules = jsonObject.getJSONArray("rules"); 
  94.          
  95.         for(Object obj : rules) { 
  96.             JSONObject rule = (JSONObject) obj; 
  97.              
  98.             String field = rule.getString("field"); 
  99.             String op = rule.getString("op"); 
  100.             String data = rule.getString("data"); 
  101.              
  102.             Criterion criterion = this.generateSearchCriterion(field, data, op); 
  103.              
  104.             if(criterion != null) { 
  105.                 criteria.add(criterion); 
  106.             } 
  107.         } 
  108.          
  109.         return criteria; 
  110.     } 
  111.     //getter和setter 
  112.     ... 

经过如上修改,JqGridBaseAction类可以接受单条件查询和复杂条件查询请求了。


3. 工具条查询

再来看看工具条查询,工具条查询主要依靠jqGrid的filterToolbar方法:
   $("#grid_id").filterToolbar(options);
或者
    $("#grid_id").jqGrid('filterToolbar',options);


主要的选项包括:

  • autosearch :当在查询工具条的输入框中点击回车,或者select选择框中的值发生改变的时候,search参数将设为true,并触发ajax请求。默认为true。
  • beforeSearch :查询前触发的事件函数。如果返回true,则不继续出发查询;在这种情况中,可以自己构建查询参数来查询数据。其他返回类型,都会触发查询。
  • afterSearch :查询后触发的事件函数。
  • beforeClear :当清理输入值之前触发的事件函数(例如clearToolbar方法(稍后介绍))。如果设为true,则不继续触发清理查询事件;这种情况下,可以自己构建参数来从Server获得数据。其他返回类型,都会触发事件。
  • afterClear :当清理输入值之后触发的事件函数(例如clearToolbar方法(稍后介绍))。
  • searchOnEnter :如果设为true,就参考autosearch;如果设为false,则输入字符后,立即进行查询。
  • stringResult :决定如何发送查询参数,如果设为false,则按key:value对的形式,发送参数;如果设为true,则按照复杂条件查询的方式,发送查询参数(其中包含json格式的filters参数)。
  • groupOp :只有stringResult为true时,此选项才有效;其值可以为AND或OR;默认为AND。

注:sopt选项在此方法中不会起作用。

在stringResult不为true的情况下,查询参数是这样的:

[javascript] view plain copy
  1. firstName:  FN-cjxxxds3 
  2. lastName:   LN-3iviu7o 
  3. nd: 1278692114137 
  4. page:   1 
  5. rows:   15 
  6. search: true 
  7. sidx:    
  8. sord:   asc 
  9. telNo:  TEL-gzbn1w 

而当stringResult设为true的情况下,查询参数会按照复杂条件查询的方式发送:

[javascript] view plain copy
  1. filters:    {"groupOp":"AND","rules":[{"field":"lastName","op":"bw","data":"LN-3iviu7o"},{"field":"firstName","op":"bw","data":"FN-cjxxxds3"},{"field":"telNo","op":"bw","data":"TEL-gzbn1w"}]} 
  2. nd: 1278692302168 
  3. page:   1 
  4. rows:   15 
  5. search: true 
  6. sidx:    
  7. sord:   asc 

工具条查询相关的附加方法:

  • triggerToolbar :当调用此方法,search参数会变为true,并向Server提交ajax请求;
  • clearToolbar :当调用此方法,清除输入值,并将search参数设为false,向Server提交ajax请求;
  • toggleToolbar :打开/关闭查询工具条。

注意以上三种附加方法的调用方式为:
$("#gridTable")[0].triggerToolbar();

注:一定不能少了“[0]”。

4. 自定义查询

虽然官方文档里将这种查询方式成为自定义查询,但其实就是工具条查询的变种。无非是改变了查询工具条的位置以及构建方式。

首先需要在html页面中建立一个区域,用于存放输入查询条件的表单,例如:
<div id="mysearch"></div>

然后构建查询工具条:
    $("#mysearch").filterGrid('#grid_id',options);
或者
    $("#mysearch").jqGrid('filterGrid','#grid_id',options);
   
主要选项:

  • gridModel :默认为false;如果设为true,则使用colModel中的name、index、edittype、editoptions、search等属性来构建查询(只有colModel的search属性为true的列会被用来构建查询表单);如果此项被设为false,则应构建一个filterModel数组来处理查询。
  • gridNames :默认为false;仅当gridModel为true的时候有效,当此项设为true时,会从jqGrid的colNames选项或得每列的标题。
  • filterModel :当gridModel为false是应该使用该属性构建查询表单。(稍后介绍)
  • formtype :定义查询表单应该是横向排列的还是纵向排列的。
  • autosearch :设为true时,当输入框中回车或select选择框值改变时,触发查询;设为false时,通过按钮触发查询。默认为true。
  • formclass/tableclass/buttonclass :应用于表单的样式。


其他选项,可在真正使用时,查询文档。

filterModel: [

{label:'LableFild', name: 'colname', stype: 'select', defval: 'default_value', surl: 'someurl', sopt:{optins for the select}},

]

注:由于传递查询参数的方式与工具条查询在stringResult不为true的情况下类似,即key:value对的格式,因此这种查询方式对于JqGridBaseAction类来说用处不大。

附加方法:

  • triggerSearch :触发查询;
  • clearSearch :清除查询表单中的值,并使用空表单或默认值从Server获得数据。

var sg = jQuery("#mysearch").filterGrid(...)[0];
sg.triggerSearch();
sg.clearSearch();
sg.triggerSearch();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值