多字段查询,绝对于单字段的过滤而言,可以称得上是高级查询了。见下图。
另外,比拟于我上一篇文章中的转换对象为Json数据的方式,本文中直接应用了JSONObect.fromObject方法,是不是更简单了!! 首先,其实默认jqGrid就有这个功能,所以,向上一篇文章中的例子一样,根本上不需要在js中增加其余的代码。
单字段查询,jqGrid向服务器传递的参数是searchField、searchString、searchOper这三个参数。多字段查询的时候,jqGrid不再采取这种方法,由于多个查询前提,参数数量就不是固定的了。这种情形下,jqGrid向服务器传递的参数是一个名字叫做filters的json字符串。类似于如下的情势: OK,在最后看一下我们的Dao实现类是如何实现的吧。 $(document).ready(function(){$("#grid").jqGrid({ url:'queryAllBrand.action',datatype: "json",mtype: 'POST', colNames:['品牌ID','品牌代码', '品牌名称', '品牌状况','最后修正时光'], colModel:[ {name:'brandId',index:'brandId', width:90}, {name:'code',index:'code', width:110}, {name:'brandName',index:'brandName', width:100}, {name:'status',index:'status', width:80}, {name:'lastModifiedDatetime',index:'lastModifiedDatetime', width:100} ], rowNum:30, rowList:[30,40,50], pager: '#nav', sortname: 'brandId', viewrecords: true, width: 500, height: 500, sortorder: "ASC",jsonReader: {repeatitems : false,id: "0"},caption: "品牌信息"}).navGrid('#nav',{edit:false,add:false,del:false}).searchGrid({multipleSearch:true});});大家可以看到最后一句话:.searchGrid({multipleSearch:true}),对,就是这么简单。(不外这种拼接调用的方式有一个问题。页面进入的时候,默认就会出来一个查询框,就像上面的图显示的一样,这感到很不爽!暂时还没有找到好的措施!!??) 那么这种方式和单字段查询的差别在什么处所呢?
@SuppressWarnings("unchecked")public String queryAllBrand(){try{if(page == null ) page= "1";if(sidx==null) sidx ="brandId";if(rows==null) rows ="30";if(sord==null) sord ="asc";if(_search == null) _search="";if(nd == null) nd = "0";log.info("Page="+page+";sidx="+sidx+";rows="+rows+";sord="+sord+";_search="+_search+";nd="+nd);log.info("searchField="+searchField+";searchValue="+searchString+";searchOper="+searchOper);log.info("filters="+filters);JqGridSearchTo to = new JqGridSearchTo();if(_search.equals("true") && filters ,皇冠比分网!= null ){JSONObject filt = JSONObject.fromObject(filters);Map m = new HashMap();m.put("rules",二八杠, JqGridSearchDetailTo.class);to = (JqGridSearchTo)JSONObject.toBean(filt, JqGridSearchTo.class, m);log.info(to.toString());}to.setPage(Integer.parseInt(page));to.setRows(Integer.parseInt(rows));to.setSidx(sidx);to.setSord(sord);to.setSearchField(searchField);to.setSearchOper(searchOper);to.setSearchString(searchString);to.set_search(Boolean.parseBoolean(_search));PageModel pm = this.brandService.findAll(to);//封装成JSON对象返回HttpServletResponse response = ServletActionContext.getResponse();response.setContentType("text/json; charset=UTF-8");PrintWriter out = response.getWriter();JSONObject ja = JSONObject.fromObject(pm);out.print(ja.toString());}catch(Exception e){e.printStackTrace();}return null;}这里需要说明一下的是:我们在转换jqGrid上传的json数据的时候,不直接用JSONObject.toBean(filt,JqGridSearchTo.class)这种方式,而是首先定义了一个Map对象,并指定了rules转换的目的对象。这是因为如果不必Map指定rules的List包括的对象类,那么,json-lib默认会把rules的List中包含的对象转换成一个叫做ezmorphDynaBean的对象,而不会依照我们的定义转换成JqGridSearchDetailTo对象。 filters = {"groupOp":"AND", "rules":[ {"field":"invdate","op":"ge","data":"2007-10-06"}, {"field":"invdate","op":"le","data":"2007-10-20"}, {"field":"name","op":"bw","data":"Client 3"} ] }晓得了这一点,我们就可以在Action类中定义一个变量是filters,然后用json-lib包供给的JSONObject类来进行json参数的解析。 /** * 根据表名称的别名以及JqGridSearchTo的查询条件组合HQL语句 * @param alias 查询对象对应的别号 * @param to * @return */public static String getCombOperation(String alias,JqGridSearchTo to){StringBuilder result = new StringBuilder("");if (to != null) {if(!to.get_search()){ //不是查询,则直接组合排序条件即可result.append(" order by ");result.append(alias);result.append(".");result.append(to.getSidx());result.append(" "+to.getSord());}else if (to.get_search() && to.getSearchField() != null && to.getSearchOper() != null ) {//只是单字段的查询 String cond = SearchOperationUtil.getOperation(to.getSearchField(), to.getSearchOper(), to.getSearchString()); if(cond != null && cond.trim().length() != 0){ result.append(" WHERE ");result.append(alias);result.append("."); result.append(cond); }result.append(" order by ");result.append(alias);result.append(".");result.append(to.getSidx());result.append(" "+to.getSord());}else if (to.get_search() && to.getGroupOp() != null && to.getRules()!= null && to.getRules().size() != 0){//多字段的组合查询String groupOp = to.getGroupOp();Iterator it = to.getRules().iterator();result.append(" WHERE ");int i = 0;while (it.hasNext()) { //轮回处理所有的查询条件i++;JqGridSearchDetailTo dto = (JqGridSearchDetailTo) it.next();result.append(alias);result.append(".");result.append(SearchOperationUtil.getOperation(dto.getField(), dto.getOp(), dto.getData()));if (i < to.getRules().size())result.append(" " + groupOp + " ");}result.append(" ORDER BY ");result.append(alias);result.append(".");result.append(to.getSidx());result.append(" "+to.getSord());}}log.info(result.toString());return result.toString();}
然后在dao类中,像如下这样进行查询和返回 public class JqGridSearchTo implements java.io.Serializable{private String groupOp;//多字段查询时候组类型,主要是AND或者ORprivate List rules; //多字段查询时候,查询条件的聚集private int page;//当前第几页private int rows;//每页显示多少条数据private String sidx; //排序字段private String sord;//排序类型 ASC或者DESCprivate boolean _search;//是否是查询 true 或者 falseprivate String nd;//临时不明白啥用的private String searchField;//单字段查询的时候,查询字段名称private String searchString;//单字段查询的时候,查询字段的值private String searchOper;//单字段查询的时候,查询的操作public JqGridSearchTo(){}......//省略Getter和Setter方法定义}然后定义jqGridSearchDetailTo对象,这个对象只是为多字段查询的rules中的查询条件设计的,相对十分简单: 当然了,在Action类中,我们还需要独自设置多少个属性字段,并同时天生其相应的Getter跟Setter。 @SuppressWarnings("unchecked")public PageModel findAll(JqGridSearchTo to){ if (to == null )return null;Session s = null;try{s = this.getSession();int page = to.getPage();int rows = to.getRows();String whereCond = SearchOperationUtil.getCombOperation("brand", to); //得到总记载数 String queryCountHql = "select count(*) from MProductBrand brand" + whereCond; Query query = s.createQuery(queryCountHql); int records = ((Long)query.uniqueResult()).intValue(); int offset = (page-1) * rows; List datas = s.createQuery("from MProductBrand brand" + whereCond) .setFirstResult(offset) .setMaxResults(rows) .list(); //得到成果集 PageModel pm = new PageModel(); int totalPage = records/rows; if(records % rows > 0) totalPage += 1; pm.setTotal(totalPage); pm.setRows(datas); pm.setPage(page); pm.setRecords(records); return pm; }finally{if(s!=null)s.close();}}看起来比以前更简略了。 这里需要留神的几点分辨说明如下: 而后大家看看Action中的履行方式类的定义: public class JqGridSearchDetailTo implements java.io.Serializable{private String field; //查询字段private String op;//查询操作private String data;//抉择的查询值public JqGridSearchDetailTo(){}......//省略Getter和Setter方法定义}这里需要说明一下,大家应当看到了,这两个类定义的属性和获取的json数据格式是一样的。这就便利json-lib进行转换。 private String searchField;private String searchString;private String searchOper;......@SuppressWarnings("unchecked")public String queryAllBrand(){try{if(page == null ) page= "1";if(sidx==null) sidx ="brandId";if(rows==null) rows ="30";if(sord==null) sord ="asc";if(_search == null) _search="";if(nd == null) nd = "0";log.info("Page="+page+";sidx="+sidx+";rows="+rows+";sord="+sord+";_search="+_search+";nd="+nd);log.info("searchField="+searchField+";searchValue="+searchString+";searchOper="+searchOper);PageModel pm = this.brandService.findAll(Integer.parseInt(page), Integer.parseInt(rows),sidx,sord,searchField,searchString,searchOper);//封装成JSON对象返回HttpServletResponse response = ServletActionContext.getResponse();response.setContentType("text/json; charset=UTF-8");PrintWriter out = response.getWriter();JSONObject obj = new JSONObject();obj.put("page", pm.getPage());obj.put("total",pm.getTotal());obj.put("records",pm.getRecords());JSONArray lineitemArray = new JSONArray();List data = pm.getDatas();Iterator it = data.iterator();while (it.hasNext()){MProductBrand mpb = (MProductBrand)it.next();lineitemArray.add(mpb.getJSON());}obj.put("rows", lineitemArray);out.print(obj.toString());}catch(Exception e){e.printStackTrace();}return null;}看上面这个代码可能会有点糊涂,因为我们的Pojo对象中,还有一个主要的办法,把POJO转换为JSON对象。 大家可以先看看图片,对单字段查询有一个直观的懂得(图片起源于jqGrid的wiki) 第三,点击上面图中的"Find"按钮之后,jqGrid会额定的向服务器发送几个参数从前。想必你已经猜到了,这些参数就是图片中显示的:查询字段searchField,查询操作searchOper以及查询值searchString。这里之所以说是额外的参数,是相对默认情况下的参数,好比前一篇文章中所说的page,sidx,sord,皇冠足球比分网,rows,_search,nd这些参数而言的。当然,这里_search参数的值是true。 页面上显示的操作,主要包含'equal', 'not equal', 'less', 'less or equal','greater','greater or equal', 'begins with','does not begin with','is in','is not in','ends with','does not end with','contains','does not contain'。相应的,后盾获取到的searchOper的值,对应的是'eq','ne','lt','le','gt','ge','bw','bn','in','ni','ew','en','cn','nc'。 然后就该从新设定一个方法来解析我们获取到的查询条件了。
//注意,JSON数据插入的次序是和页面显示的顺序相干的。public JSONObject getJSON(){JSONObject json = new JSONObject();json.put("brandId", brandId);json.put("code", code);json.put("brandName", brandName);json.put("status", status);return json;}感觉比拟丑恶的,还是那个getOperation方法,一个是自身还有良多的bug,比如对空值的处理不够完美;二是对日期类型的处理功能基础上没有等等。呵呵,暂时先这样吧!有兴致大家也可以帮忙修改一下!
多字段查询的jqGrid调用方式如下: 为了方便转换,我们这里定义了两个Transfer Object对象,分离是JqGridSearchTo对象以及JqGridSearchDetailTo对象。
其次,哪些字段能作为单字段查问,哪些字段不能,这是在jqGrid的colModel属性中能够进行设置的。比方,假如咱们对某一个列的数据设置如下:{name:'userName',index:'usrName', width:110,search=false} 那么这个userName列是不会在单字段查询中显示出来的。
最最简单的主意就是像我这养,写一个方法来处理:(以下的例子是基于Hibernate写的) 第四,最烦处置的,就是如何把我们的searchOper的参数值,转换为对数据库记载的查询操作。 JqGridSearchTo对象的定义如下:(为了方便,我们把一些其他jqGrid上传的参数也封装了进去)
以上局部代码存在一些隐患,请勿用于你的正式环境!
json-lib包不仅提供了把Bean或容器类List、Map等转换为json格式数据的方法,而且提供了把json格式数据转换为容器类或者Bean类对象的方法。 (责任编辑:admin) |


