多字段查詢,相對於單字段的過濾而言,能夠稱得上是高級查詢了。見下圖。java
多字段查詢的jqGrid調用方式以下:json
$(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}),對,就是這麼簡單。(不過這種拼接調用的方式有一個問題。頁面進入的時候,默認就會出來一個查詢框,就像上面的圖顯示的同樣,這感受很不爽!暫時尚未找到好的辦法!!??)服務器
那麼這種方式和單字段查詢的區別在什麼地方呢?app
單字段查詢,jqGrid向服務器傳遞的參數是searchField、searchString、searchOper這三個參數。多字段查詢的時候,jqGrid再也不採用這種方式,由於多個查詢條件,參數數目就不是固定的了。這種狀況下,jqGrid向服務器傳遞的參數是一個名字叫作filters的json字符串。相似於以下的形式:ui
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參數的解析。this
json-lib包不只提供了把Bean或容器類List、Map等轉換爲json格式數據的方法,並且提供了把json格式數據轉換爲容器類或者Bean類對象的方法。url
爲了方便轉換,咱們這裏定義了兩個Transfer Object對象,分別是JqGridSearchTo對象以及JqGridSearchDetailTo對象。spa
JqGridSearchTo對象的定義以下:(爲了方便,咱們把一些其餘jqGrid上傳的參數也封裝了進去)設計
public class JqGridSearchTo implements java.io.Serializable{ private String groupOp; //多字段查詢時分組類型,主要是AND或者OR private List rules; //多字段查詢時候,查詢條件的集合 private int page; //當前第幾頁 private int rows; //每頁顯示多少條數據 private String sidx; //排序字段 private String sord; //排序類型 ASC或者DESC private boolean _search; //是不是查詢 true 或者 false private String nd; //暫時不清楚啥用的 private String searchField; //單字段查詢的時候,查詢字段名稱 private String searchString; //單字段查詢的時候,查詢字段的值 private String searchOper; //單字段查詢的時候,查詢的操做 public JqGridSearchTo(){ } ......//省略Getter和Setter方法定義 }
而後定義jqGridSearchDetailTo對象,這個對象只是爲多字段查詢的rules中的查詢條件設計的,相對很是簡單:code
public class JqGridSearchDetailTo implements java.io.Serializable{ private String field; //查詢字段 private String op; //查詢操做 private String data; //選擇的查詢值 public JqGridSearchDetailTo(){ } ......//省略Getter和Setter方法定義 }
這裏須要說明一下,你們應該看到了,這兩個類定義的屬性和獲取的json數據格式是同樣的。這就方便json-lib進行轉換。
而後你們看看Action中的執行方法類的定義:
@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對象。
另外,相比於我上一篇文章中的轉換對象爲Json數據的方式,本文中直接使用了JSONObect.fromObject方法,是否是更簡單了!!
而後就該從新設定一個方法來解析咱們獲取到的查詢條件了。
/** * 根據表名稱的別名以及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(); }
OK,在最後看一下咱們的Dao實現類是如何實現的吧。
@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(); } }
看起來比之前更簡單了。
OK,That’s all !
以上部分代碼存在一些隱患,請勿用於您的正式環境!