jqGrid与Struts2的结合应用(五) —— 结合Action类进行数据查询
2012-04-15 15:07
501 查看
这篇主要讲的是jqGrid的查找功能。
根据官方文档的介绍,jqGrid的查找功能分四种:
工具条查询;
自定义查询;
单条件表单查询;
高级表单查询(复杂条件查询);
我个人认为这样划分比较复杂,可以基本分为两大类,即:
表单查询:包括单条件查询和高级查询(复杂条件查询);
工具条查询:包括工具条查询和自定义查询;
而这两大类中,也以表单查询更常用。
现在逐个说明一下(我改变了官方文档的讲解顺序,我觉得自己的这个顺序,更直观,更靠近现实使用)。
1. 单条件表单查询
先从服务器端看起,为了配合jqGrid的查询功能,我们需要在JqGridBaseAction类中添加几个成员变量。成员变量的名字必须和jqGrid的prmNames选项中定义的参数名相对应上(具体参考本系列文章的第一篇)。
改进后的JqGridBaseAction类代码:
[java]
view plaincopyprint?
package cn.gengv.struts2ex.jqGrid;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.byzl.hare.dao.impl.Criterion;
import com.byzl.hare.dao.impl.Criterion.CompareType;
import com.opensymphony.xwork2.ActionSupport;
@SuppressWarnings("serial")
public abstract class JqGridBaseAction<T> extends ActionSupport {
private List<T> gridModel = Collections.emptyList();
private Integer rows = 0;
private Integer page = 0;
private Integer total = 0;
private Integer record = 0;
private String sord;
private String sidx;
// (1)添加和查询有关的成员变量search、searchField、searchString、searchOper
private boolean search;
private String searchField;
private String searchString;
private String searchOper;
public abstract int getResultSize();
public abstract List<T> listResults(int from, int length);
// (2)添加用于根据条件进行查询的方法
public abstract int getResultSize(List<Criterion> criteria);
public abstract List<T> listResults(List<Criterion> criteria, int from, int length);
public String refreshGridModel() {
try {
List<Criterion> criteria = Collections.emptyList();
// (3)如果search值为true,则表明是查询请求
if(search == true) {
// (4)通过searchField、searchString、searchOper生成通用的查询条件
Criterion criterion = this.generateSearchCriterion(searchField, searchString, searchOper);
criteria = new ArrayList<Criterion>();
if(criterion != null) {
criteria.add(criterion);
}
}
int from = rows * (page - 1);
int length = rows;
List<T> results = Collections.emptyList();
if(!criteria.isEmpty()) { // (5)如果criteria列表不为空,则根据条件进行查询
record = this.getResultSize(criteria);
results = this.listResults(criteria, from, length);
} else {
record = this.getResultSize();
results = this.listResults(from, length);
}
this.setGridModel(results);
total = (int) Math.ceil((double) record / (double) rows);
return SUCCESS;
} catch (Exception e) {
e.printStackTrace();
this.addActionError(e.getMessage());
return ERROR;
}
}
// (6)通过searchField、searchString、searchOper三个参数生成Criterion的方法
public Criterion generateSearchCriterion(String searchField,
String searchString, String searchOper) {
Criterion criterion = null;
// (7)如果searchField、searchString、searchOper均不为null,且searchString不为空字符串时,则创建Criterion
if (searchField != null && searchString != null
& searchString.length() > 0 && searchOper != null) {
if ("eq".equals(searchOper)) {
criterion = Criterion.getEqualCriterion(searchField,
searchString, null);
} else if ("ne".equals(searchOper)) {
criterion = Criterion.getCompareCriterion(CompareType.NE,
searchField, searchString, null);
} else if ("lt".equals(searchOper)) {
criterion = Criterion.getCompareCriterion(CompareType.LT,
searchField, searchString, null);
} else if ("le".equals(searchOper)) {
criterion = Criterion.getCompareCriterion(CompareType.LTE,
searchField, searchString, null);
} else if ("gt".equals(searchOper)) {
criterion = Criterion.getCompareCriterion(CompareType.GT,
searchField, searchString, null);
} else if ("ge".equals(searchOper)) {
criterion = Criterion.getCompareCriterion(CompareType.GTE,
searchField, searchString, null);
} else if ("bw".equals(searchOper)) {
criterion = Criterion.getLikeCriterion(searchField,
searchString + "%", null);
} else if ("bn".equals(searchOper)) {
criterion = Criterion.getNotLikeCriterion(searchField,
searchString + "%", null);
} else if ("ew".equals(searchOper)) {
criterion = Criterion.getLikeCriterion(searchField, "%"
+ searchString, null);
} else if ("en".equals(searchOper)) {
criterion = Criterion.getNotLikeCriterion(searchField, "%"
+ searchString, null);
} else if ("cn".equals(searchOper)) {
criterion = Criterion.getLikeCriterion(searchField, "%"
+ searchString + "%", null);
} else if ("nc".equals(searchOper)) {
criterion = Criterion.getNotLikeCriterion(searchField, "%"
+ searchString + "%", null);
}
}
return criterion;
}
// getter和setter
...
}
简要说明一下:
我把Criterion分成4类:EqualCriterion、CompareCriterion、LikeCriterion、NotLikeCriterion。(具体划分方式全为使用方便)
另外还有两个静态方法:convertToSql和getCriteriaValues,用来将Criterion列表转化为JdbcTemplate需要的SQL子句和参数列表。
回到ListContactsAction,代码如下:
[java]
view plaincopyprint?
package cn.gengv.struts2ex.jqGrid;
import java.util.Collections;
import java.util.List;
import com.byzl.hare.dao.impl.Criterion;
import com.byzl.hare.model.Contact;
import com.byzl.hare.service.ContactService;
@SuppressWarnings("serial")
public class ListContactsAction extends JqGridBaseAction<Contact> {
private ContactService contactService;
@Override
public String execute() {
return this.refreshGridModel();
}
@Override
public int getResultSize() {
return this.contactService.queryResultsCount(null);
}
@Override
public List<Contact> listResults(int from, int length) {
return this.contactService.queryByPage(null, from, length);
}
@Override
public int getResultSize(List<Criterion> criteria) {
return this.contactService.queryResultsCount(criteria);
}
@Override
public List<Contact> listResults(List<Criterion> criteria, int from, int length) {
List<Contact> results = Collections.emptyList();
results = this.contactService.queryByPage(criteria, from, length);
return results;
}
public void setContactService(ContactService contactService) {
this.contactService = contactService;
}
}
等同于
[javascript]
view plaincopyprint?
$("#gridTable").jqGrid("navGrid", "#gridPager", {},{},{},{},
{ // 与查询相关的prmSearch参数
caption: "查找",
Find: "Go!",
closeAfterSearch: true
},{});
或者
[javascript]
view plaincopyprint?
var complexCriteriaSearch = function() {
$("#gridTable").jqGrid("searchGrid", {
caption: "查找",
Find: "Go!",
closeAfterSearch: true,
multipleSearch: true,
groupOps: [{ op: "AND", text: "全部" }]
});
};
而复杂条件的查询的参数是下面这种形式:
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 plaincopyprint?
filters: {"groupOp":"AND","rules":[{"field":"id","op":"le","data":"1500"},{"field":"lastName","op":"bw","data":"LN-3"},{"field":"email","op":"cn","data":"sy"}]}
nd: 1278688110637
page: 1
rows: 15
search: true
sidx:
sord: asc
其余部分的代码:
[java]
view plaincopyprint?
package cn.gengv.struts2ex.jqGrid;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import com.byzl.hare.dao.impl.Criterion;
import com.byzl.hare.dao.impl.Criterion.CompareType;
import com.opensymphony.xwork2.ActionSupport;
@SuppressWarnings("serial")
public abstract class JqGridBaseAction<T> extends ActionSupport {
private List<T> gridModel = Collections.emptyList();
private Integer rows = 0;
private Integer page = 0;
private Integer total = 0;
private Integer record = 0;
private String sord;
private String sidx;
private boolean search;
private String searchField;
private String searchString;
private String searchOper;
public abstract int getResultSize();
public abstract List<T> listResults(int from, int length);
// (1)添加filters成员变量
private String filters;
public abstract int getResultSize(List<Criterion> criteria);
public abstract List<T> listResults(List<Criterion> criteria, int from, int length);
public String refreshGridModel() {
try {
List<Criterion> criteria = Collections.emptyList();
if(search == true) {
criteria = new ArrayList<Criterion>();
// (2)将Filter转化为Criterion列表,并加入总的Criterion列表
if(filters != null && filters.length()>0) {
criteria.addAll(this.generateSearchCriteriaFromFilters(filters));
}
// (3)将searchField、searchString、searchOper转化为Criterion,并加入总的Criterion列表
Criterion criterion = this.generateSearchCriterion(searchField, searchString, searchOper);
if(criterion != null) {
criteria.add(criterion);
}
}
int from = rows * (page - 1);
int length = rows;
List<T> results = Collections.emptyList();
if(!criteria.isEmpty()) {
record = this.getResultSize(criteria);
results = this.listResults(criteria, from, length);
} else {
record = this.getResultSize();
results = this.listResults(from, length);
}
this.setGridModel(results);
total = (int) Math.ceil((double) record / (double) rows);
return SUCCESS;
} catch (Exception e) {
e.printStackTrace();
this.addActionError(e.getMessage());
return ERROR;
}
}
public Criterion generateSearchCriterion(String searchField,
String searchString, String searchOper) {
...
}
public List<Criterion> generateSearchCriteriaFromFilters(String filters) {
List<Criterion> criteria = new ArrayList<Criterion>();
JSONObject jsonObject = JSONObject.fromObject(filters);
JSONArray rules = jsonObject.getJSONArray("rules");
for(Object obj : rules) {
JSONObject rule = (JSONObject) obj;
String field = rule.getString("field");
String op = rule.getString("op");
String data = rule.getString("data");
Criterion criterion = this.generateSearchCriterion(field, data, op);
if(criterion != null) {
criteria.add(criterion);
}
}
return criteria;
}
//getter和setter
...
}
而当stringResult设为true的情况下,查询参数会按照复杂条件查询的方式发送:
[javascript]
view plaincopyprint?
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"}]}
nd: 1278692302168
page: 1
rows: 15
search: true
sidx:
sord: asc
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"}]}
nd: 1278692302168
page: 1
rows: 15
search: true
sidx:
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();
根据官方文档的介绍,jqGrid的查找功能分四种:
工具条查询;
自定义查询;
单条件表单查询;
高级表单查询(复杂条件查询);
我个人认为这样划分比较复杂,可以基本分为两大类,即:
表单查询:包括单条件查询和高级查询(复杂条件查询);
工具条查询:包括工具条查询和自定义查询;
而这两大类中,也以表单查询更常用。
现在逐个说明一下(我改变了官方文档的讲解顺序,我觉得自己的这个顺序,更直观,更靠近现实使用)。
1. 单条件表单查询
先从服务器端看起,为了配合jqGrid的查询功能,我们需要在JqGridBaseAction类中添加几个成员变量。成员变量的名字必须和jqGrid的prmNames选项中定义的参数名相对应上(具体参考本系列文章的第一篇)。
改进后的JqGridBaseAction类代码:
[java]
view plaincopyprint?
package cn.gengv.struts2ex.jqGrid;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.byzl.hare.dao.impl.Criterion;
import com.byzl.hare.dao.impl.Criterion.CompareType;
import com.opensymphony.xwork2.ActionSupport;
@SuppressWarnings("serial")
public abstract class JqGridBaseAction<T> extends ActionSupport {
private List<T> gridModel = Collections.emptyList();
private Integer rows = 0;
private Integer page = 0;
private Integer total = 0;
private Integer record = 0;
private String sord;
private String sidx;
// (1)添加和查询有关的成员变量search、searchField、searchString、searchOper
private boolean search;
private String searchField;
private String searchString;
private String searchOper;
public abstract int getResultSize();
public abstract List<T> listResults(int from, int length);
// (2)添加用于根据条件进行查询的方法
public abstract int getResultSize(List<Criterion> criteria);
public abstract List<T> listResults(List<Criterion> criteria, int from, int length);
public String refreshGridModel() {
try {
List<Criterion> criteria = Collections.emptyList();
// (3)如果search值为true,则表明是查询请求
if(search == true) {
// (4)通过searchField、searchString、searchOper生成通用的查询条件
Criterion criterion = this.generateSearchCriterion(searchField, searchString, searchOper);
criteria = new ArrayList<Criterion>();
if(criterion != null) {
criteria.add(criterion);
}
}
int from = rows * (page - 1);
int length = rows;
List<T> results = Collections.emptyList();
if(!criteria.isEmpty()) { // (5)如果criteria列表不为空,则根据条件进行查询
record = this.getResultSize(criteria);
results = this.listResults(criteria, from, length);
} else {
record = this.getResultSize();
results = this.listResults(from, length);
}
this.setGridModel(results);
total = (int) Math.ceil((double) record / (double) rows);
return SUCCESS;
} catch (Exception e) {
e.printStackTrace();
this.addActionError(e.getMessage());
return ERROR;
}
}
// (6)通过searchField、searchString、searchOper三个参数生成Criterion的方法
public Criterion generateSearchCriterion(String searchField,
String searchString, String searchOper) {
Criterion criterion = null;
// (7)如果searchField、searchString、searchOper均不为null,且searchString不为空字符串时,则创建Criterion
if (searchField != null && searchString != null
& searchString.length() > 0 && searchOper != null) {
if ("eq".equals(searchOper)) {
criterion = Criterion.getEqualCriterion(searchField,
searchString, null);
} else if ("ne".equals(searchOper)) {
criterion = Criterion.getCompareCriterion(CompareType.NE,
searchField, searchString, null);
} else if ("lt".equals(searchOper)) {
criterion = Criterion.getCompareCriterion(CompareType.LT,
searchField, searchString, null);
} else if ("le".equals(searchOper)) {
criterion = Criterion.getCompareCriterion(CompareType.LTE,
searchField, searchString, null);
} else if ("gt".equals(searchOper)) {
criterion = Criterion.getCompareCriterion(CompareType.GT,
searchField, searchString, null);
} else if ("ge".equals(searchOper)) {
criterion = Criterion.getCompareCriterion(CompareType.GTE,
searchField, searchString, null);
} else if ("bw".equals(searchOper)) {
criterion = Criterion.getLikeCriterion(searchField,
searchString + "%", null);
} else if ("bn".equals(searchOper)) {
criterion = Criterion.getNotLikeCriterion(searchField,
searchString + "%", null);
} else if ("ew".equals(searchOper)) {
criterion = Criterion.getLikeCriterion(searchField, "%"
+ searchString, null);
} else if ("en".equals(searchOper)) {
criterion = Criterion.getNotLikeCriterion(searchField, "%"
+ searchString, null);
} else if ("cn".equals(searchOper)) {
criterion = Criterion.getLikeCriterion(searchField, "%"
+ searchString + "%", null);
} else if ("nc".equals(searchOper)) {
criterion = Criterion.getNotLikeCriterion(searchField, "%"
+ searchString + "%", null);
}
}
return criterion;
}
// getter和setter
...
}
[java] view plaincopyprint? package com.byzl.hare.dao.impl; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class Criterion { public static enum CriterionType { EQUAL, LIKE, COMPARE, NOT_LIKE } public static enum CompareType { GT, GTE, LT, LTE, EQ, NE } private CriterionType criterionType; private String tableName; private String field; private Object value; // 将Criteria转换为SQL条件语句 public static String convertToSql(List<Criterion> criteria) { String criteriaString = ""; StringBuilder sb = new StringBuilder(); for (Criterion criterion : criteria) { String prefix = criterion.getFieldPrefix(); switch (criterion.getCriterionType()) { case EQUAL: sb.append(prefix + criterion.getField() + "=? and "); break; case LIKE: sb.append(prefix + criterion.getField() + " like ? and "); break; case NOT_LIKE: sb.append(prefix + criterion.getField() + " not like ? and "); break; case COMPARE: CompareType compareType = ((CompareCriterion) criterion) .getCompareType(); switch (compareType) { case EQ: sb.append(prefix + criterion.getField() + "=? and "); break; case NE: sb.append(prefix + criterion.getField() + "<>? and "); break; case GT: sb.append(prefix + criterion.getField() + ">? and "); break; case GTE: sb.append(prefix + criterion.getField() + ">=? and "); break; case LT: sb.append(prefix + criterion.getField() + "<? and "); break; case LTE: sb.append(prefix + criterion.getField() + "<=? and "); break; } break; } } int i = -1; if ((i = sb.lastIndexOf(" and ")) != -1) { criteriaString = sb.substring(0, i); } return criteriaString; } // 将Criteria各条件的值转换为List<Object> public static List<Object> getCriteriaValues(List<Criterion> criteria) { List<Object> criteriaValues = criteria.isEmpty() ? Collections .emptyList() : new ArrayList<Object>(); for (Criterion criterion : criteria) { criteriaValues.add(criterion.getValue()); } return criteriaValues; } public CriterionType getCriterionType() { return criterionType; } public void setCriterionType(CriterionType criterionType) { this.criterionType = criterionType; } public String getField() { return field; } public void setField(String field) { this.field = field; } public Object getValue() { return value; } public void setValue(Object value) { this.value = value; } public static Criterion getCompareCriterion(CompareType compareType, String field, Object value, String tableName) { CompareCriterion compareCriterion = new CompareCriterion(); compareCriterion.setCriterionType(CriterionType.COMPARE); compareCriterion.setCompareType(compareType); compareCriterion.setField(field); compareCriterion.setValue(value); compareCriterion.setTableName(tableName); return compareCriterion; } public static Criterion getLikeCriterion(String field, Object value, String tableName) { LikeCriterion likeCriterion = new LikeCriterion(); likeCriterion.setCriterionType(CriterionType.LIKE); likeCriterion.setField(field); likeCriterion.setValue(value); likeCriterion.setTableName(tableName); return likeCriterion; } public static Criterion getNotLikeCriterion(String field, Object value, String tableName) { NotLikeCriterion notLikeCriterion = new NotLikeCriterion(); notLikeCriterion.setCriterionType(CriterionType.NOT_LIKE); notLikeCriterion.setField(field); notLikeCriterion.setValue(value); notLikeCriterion.setTableName(tableName); return notLikeCriterion; } public static Criterion getEqualCriterion(String field, Object value, String tableName) { EqualCriterion equalCriterion = new EqualCriterion(); equalCriterion.setCriterionType(CriterionType.EQUAL); equalCriterion.setField(field); equalCriterion.setValue(value); equalCriterion.setTableName(tableName); return equalCriterion; } public static class LikeCriterion extends Criterion { } public static class NotLikeCriterion extends Criterion { } public static class EqualCriterion extends Criterion { } public static class CompareCriterion extends Criterion { private CompareType compareType; public CompareType getCompareType() { return compareType; } public void setCompareType(CompareType compareType) { this.compareType = compareType; } } public String getTableName() { return tableName; } public void setTableName(String tableName) { this.tableName = tableName; } public String getFieldPrefix() { return (tableName == null || tableName.length() == 0) ? "" : tableName + "."; } } package com.byzl.hare.dao.impl; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class Criterion { public static enum CriterionType { EQUAL, LIKE, COMPARE, NOT_LIKE } public static enum CompareType { GT, GTE, LT, LTE, EQ, NE } private CriterionType criterionType; private String tableName; private String field; private Object value; // 将Criteria转换为SQL条件语句 public static String convertToSql(List<Criterion> criteria) { String criteriaString = ""; StringBuilder sb = new StringBuilder(); for (Criterion criterion : criteria) { String prefix = criterion.getFieldPrefix(); switch (criterion.getCriterionType()) { case EQUAL: sb.append(prefix + criterion.getField() + "=? and "); break; case LIKE: sb.append(prefix + criterion.getField() + " like ? and "); break; case NOT_LIKE: sb.append(prefix + criterion.getField() + " not like ? and "); break; case COMPARE: CompareType compareType = ((CompareCriterion) criterion) .getCompareType(); switch (compareType) { case EQ: sb.append(prefix + criterion.getField() + "=? and "); break; case NE: sb.append(prefix + criterion.getField() + "<>? and "); break; case GT: sb.append(prefix + criterion.getField() + ">? and "); break; case GTE: sb.append(prefix + criterion.getField() + ">=? and "); break; case LT: sb.append(prefix + criterion.getField() + "<? and "); break; case LTE: sb.append(prefix + criterion.getField() + "<=? and "); break; } break; } } int i = -1; if ((i = sb.lastIndexOf(" and ")) != -1) { criteriaString = sb.substring(0, i); } return criteriaString; } // 将Criteria各条件的值转换为List<Object> public static List<Object> getCriteriaValues(List<Criterion> criteria) { List<Object> criteriaValues = criteria.isEmpty() ? Collections .emptyList() : new ArrayList<Object>(); for (Criterion criterion : criteria) { criteriaValues.add(criterion.getValue()); } return criteriaValues; } public CriterionType getCriterionType() { return criterionType; } public void setCriterionType(CriterionType criterionType) { this.criterionType = criterionType; } public String getField() { return field; } public void setField(String field) { this.field = field; } public Object getValue() { return value; } public void setValue(Object value) { this.value = value; } public static Criterion getCompareCriterion(CompareType compareType, String field, Object value, String tableName) { CompareCriterion compareCriterion = new CompareCriterion(); compareCriterion.setCriterionType(CriterionType.COMPARE); compareCriterion.setCompareType(compareType); compareCriterion.setField(field); compareCriterion.setValue(value); compareCriterion.setTableName(tableName); return compareCriterion; } public static Criterion getLikeCriterion(String field, Object value, String tableName) { LikeCriterion likeCriterion = new LikeCriterion(); likeCriterion.setCriterionType(CriterionType.LIKE); likeCriterion.setField(field); likeCriterion.setValue(value); likeCriterion.setTableName(tableName); return likeCriterion; } public static Criterion getNotLikeCriterion(String field, Object value, String tableName) { NotLikeCriterion notLikeCriterion = new NotLikeCriterion(); notLikeCriterion.setCriterionType(CriterionType.NOT_LIKE); notLikeCriterion.setField(field); notLikeCriterion.setValue(value); notLikeCriterion.setTableName(tableName); return notLikeCriterion; } public static Criterion getEqualCriterion(String field, Object value, String tableName) { EqualCriterion equalCriterion = new EqualCriterion(); equalCriterion.setCriterionType(CriterionType.EQUAL); equalCriterion.setField(field); equalCriterion.setValue(value); equalCriterion.setTableName(tableName); return equalCriterion; } public static class LikeCriterion extends Criterion { } public static class NotLikeCriterion extends Criterion { } public static class EqualCriterion extends Criterion { } public static class CompareCriterion extends Criterion { private CompareType compareType; public CompareType getCompareType() { return compareType; } public void setCompareType(CompareType compareType) { this.compareType = compareType; } } public String getTableName() { return tableName; } public void setTableName(String tableName) { this.tableName = tableName; } public String getFieldPrefix() { return (tableName == null || tableName.length() == 0) ? "" : tableName + "."; } }
简要说明一下:
我把Criterion分成4类:EqualCriterion、CompareCriterion、LikeCriterion、NotLikeCriterion。(具体划分方式全为使用方便)
另外还有两个静态方法:convertToSql和getCriteriaValues,用来将Criterion列表转化为JdbcTemplate需要的SQL子句和参数列表。
回到ListContactsAction,代码如下:
[java]
view plaincopyprint?
package cn.gengv.struts2ex.jqGrid;
import java.util.Collections;
import java.util.List;
import com.byzl.hare.dao.impl.Criterion;
import com.byzl.hare.model.Contact;
import com.byzl.hare.service.ContactService;
@SuppressWarnings("serial")
public class ListContactsAction extends JqGridBaseAction<Contact> {
private ContactService contactService;
@Override
public String execute() {
return this.refreshGridModel();
}
@Override
public int getResultSize() {
return this.contactService.queryResultsCount(null);
}
@Override
public List<Contact> listResults(int from, int length) {
return this.contactService.queryByPage(null, from, length);
}
@Override
public int getResultSize(List<Criterion> criteria) {
return this.contactService.queryResultsCount(criteria);
}
@Override
public List<Contact> listResults(List<Criterion> criteria, int from, int length) {
List<Contact> results = Collections.emptyList();
results = this.contactService.queryByPage(criteria, from, length);
return results;
}
public void setContactService(ContactService contactService) {
this.contactService = contactService;
}
}
[javascript] view plaincopyprint? var singleCriterionSearch = function() { $("#gridTable").jqGrid("searchGrid", { caption: "查找", Find: "Go!", closeAfterSearch: true }); }; var singleCriterionSearch = function() { $("#gridTable").jqGrid("searchGrid", { caption: "查找", Find: "Go!", closeAfterSearch: true }); };
等同于
[javascript]
view plaincopyprint?
$("#gridTable").jqGrid("navGrid", "#gridPager", {},{},{},{},
{ // 与查询相关的prmSearch参数
caption: "查找",
Find: "Go!",
closeAfterSearch: true
},{});
[javascript] view plaincopyprint? $("#gridTable").jqGrid("navGrid", "#gridPager", {},{},{},{}, { // 与查询相关的prmSearch参数 caption: "查找", Find: "Go!", closeAfterSearch: true, multipleSearch: true, groupOps: [{ op: "AND", text: "全部" }] },{}); $("#gridTable").jqGrid("navGrid", "#gridPager", {},{},{},{}, { // 与查询相关的prmSearch参数 caption: "查找", Find: "Go!", closeAfterSearch: true, multipleSearch: true, groupOps: [{ op: "AND", text: "全部" }] },{});
或者
[javascript]
view plaincopyprint?
var complexCriteriaSearch = function() {
$("#gridTable").jqGrid("searchGrid", {
caption: "查找",
Find: "Go!",
closeAfterSearch: true,
multipleSearch: true,
groupOps: [{ op: "AND", text: "全部" }]
});
};
[javascript] view plaincopyprint? nd: 1278688214496 page: 1 rows: 15 search: true searchField: id searchOper: ge searchString: 9000 sidx: sord: asc nd: 1278688214496 page: 1 rows: 15 search: true searchField: id searchOper: ge searchString: 9000 sidx: 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 plaincopyprint?
filters: {"groupOp":"AND","rules":[{"field":"id","op":"le","data":"1500"},{"field":"lastName","op":"bw","data":"LN-3"},{"field":"email","op":"cn","data":"sy"}]}
nd: 1278688110637
page: 1
rows: 15
search: true
sidx:
sord: asc
[java] view plaincopyprint? public List<Criterion> generateSearchCriteriaFromFilters(String filters) { List<Criterion> criteria = new ArrayList<Criterion>(); JSONObject jsonObject = JSONObject.fromObject(filters); JSONArray rules = jsonObject.getJSONArray("rules"); for(Object obj : rules) { JSONObject rule = (JSONObject) obj; String field = rule.getString("field"); String op = rule.getString("op"); String data = rule.getString("data"); Criterion criterion = this.generateSearchCriterion(field, data, op); if(criterion != null) { criteria.add(criterion); } } return criteria; } public List<Criterion> generateSearchCriteriaFromFilters(String filters) { List<Criterion> criteria = new ArrayList<Criterion>(); JSONObject jsonObject = JSONObject.fromObject(filters); JSONArray rules = jsonObject.getJSONArray("rules"); for(Object obj : rules) { JSONObject rule = (JSONObject) obj; String field = rule.getString("field"); String op = rule.getString("op"); String data = rule.getString("data"); Criterion criterion = this.generateSearchCriterion(field, data, op); if(criterion != null) { criteria.add(criterion); } } return criteria; }
其余部分的代码:
[java]
view plaincopyprint?
package cn.gengv.struts2ex.jqGrid;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import com.byzl.hare.dao.impl.Criterion;
import com.byzl.hare.dao.impl.Criterion.CompareType;
import com.opensymphony.xwork2.ActionSupport;
@SuppressWarnings("serial")
public abstract class JqGridBaseAction<T> extends ActionSupport {
private List<T> gridModel = Collections.emptyList();
private Integer rows = 0;
private Integer page = 0;
private Integer total = 0;
private Integer record = 0;
private String sord;
private String sidx;
private boolean search;
private String searchField;
private String searchString;
private String searchOper;
public abstract int getResultSize();
public abstract List<T> listResults(int from, int length);
// (1)添加filters成员变量
private String filters;
public abstract int getResultSize(List<Criterion> criteria);
public abstract List<T> listResults(List<Criterion> criteria, int from, int length);
public String refreshGridModel() {
try {
List<Criterion> criteria = Collections.emptyList();
if(search == true) {
criteria = new ArrayList<Criterion>();
// (2)将Filter转化为Criterion列表,并加入总的Criterion列表
if(filters != null && filters.length()>0) {
criteria.addAll(this.generateSearchCriteriaFromFilters(filters));
}
// (3)将searchField、searchString、searchOper转化为Criterion,并加入总的Criterion列表
Criterion criterion = this.generateSearchCriterion(searchField, searchString, searchOper);
if(criterion != null) {
criteria.add(criterion);
}
}
int from = rows * (page - 1);
int length = rows;
List<T> results = Collections.emptyList();
if(!criteria.isEmpty()) {
record = this.getResultSize(criteria);
results = this.listResults(criteria, from, length);
} else {
record = this.getResultSize();
results = this.listResults(from, length);
}
this.setGridModel(results);
total = (int) Math.ceil((double) record / (double) rows);
return SUCCESS;
} catch (Exception e) {
e.printStackTrace();
this.addActionError(e.getMessage());
return ERROR;
}
}
public Criterion generateSearchCriterion(String searchField,
String searchString, String searchOper) {
...
}
public List<Criterion> generateSearchCriteriaFromFilters(String filters) {
List<Criterion> criteria = new ArrayList<Criterion>();
JSONObject jsonObject = JSONObject.fromObject(filters);
JSONArray rules = jsonObject.getJSONArray("rules");
for(Object obj : rules) {
JSONObject rule = (JSONObject) obj;
String field = rule.getString("field");
String op = rule.getString("op");
String data = rule.getString("data");
Criterion criterion = this.generateSearchCriterion(field, data, op);
if(criterion != null) {
criteria.add(criterion);
}
}
return criteria;
}
//getter和setter
...
}
[javascript] view plaincopyprint? firstName: FN-cjxxxds3 lastName: LN-3iviu7o nd: 1278692114137 page: 1 rows: 15 search: true sidx: sord: asc telNo: TEL-gzbn1w firstName: FN-cjxxxds3 lastName: LN-3iviu7o nd: 1278692114137 page: 1 rows: 15 search: true sidx: sord: asc telNo: TEL-gzbn1w
而当stringResult设为true的情况下,查询参数会按照复杂条件查询的方式发送:
[javascript]
view plaincopyprint?
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"}]}
nd: 1278692302168
page: 1
rows: 15
search: true
sidx:
sord: asc
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"}]}
nd: 1278692302168
page: 1
rows: 15
search: true
sidx:
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();
相关文章推荐
- jqGrid与Struts2的结合应用(五) ------ 结合Action类进行数据查询 .
- jqGrid与Struts2的结合应用(五) —— 结合Action类进行数据查询
- jqGrid与Struts2的结合应用(五) —— 结合Action类进行数据查询
- jqGrid与Struts2的结合应用(五) —— 结合Action类进行数据查询
- jqGrid与Struts2的结合应用(五) —— 结合Action类进行数据查询
- jqGrid与Struts2的结合应用(五) —— 结合Action类进行数据查询
- jqGrid与Struts2的结合应用(五) —— 结合Action类进行数据查询
- jqGrid与Struts2的结合应用(十) —— 真正的自定义表单查询
- jqGrid与Struts2的结合应用(十) —— 真正的自定义表单查询
- jqGrid与Struts2的结合应用(二) —— 操作Grid数据
- jqGrid与Struts2的结合应用(二) —— 操作Grid数据
- jqGrid与Struts2的结合应用(二) ------ 操作Grid数据 .
- jqGrid与Struts2的结合应用(六) ------ 使用colModel设置查询功能 .
- jqGrid与Struts2的结合应用(二) —— 操作Grid数据
- jqGrid与Struts2的结合应用(六) —— 使用colModel设置查询功能
- jqGrid与Struts2的结合应用(三) —— 使用自定义表单对话框编辑Grid数据
- jqGrid与Struts2的结合应用(三) ------ 使用自定义表单对话框编辑Grid数据 .
- jqGrid与Struts2的结合应用(二) —— 操作Grid数据
- jqGrid与Struts2的结合应用(二) —— 操作Grid数据
- jqGrid与Struts2的结合应用(十) —— 真正的自定义表单查询