jqGrid的多字段查询

多字段查询,相对于单字段的过滤而言,可以称得上是高级查询了。见下图。

jqGrid的多字段查询_第1张图片

多字段查询的jqGrid调用方式如下:

			$(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}),对,就是这么简单。(不过这种拼接调用的方式有一个问题。页面进入的时候,默认就会出来一个查询框,就像上面的图显示的一样,这感觉很不爽!暂时还没有找到好的办法!!??)

那么这种方式和单字段查询的区别在什么地方呢?

单字段查询,jqGrid向服务器传递的参数是searchField、searchString、searchOper这三个参数。多字段查询的时候,jqGrid不再采用这种方式,因为多个查询条件,参数数目就不是固定的了。这种情况下,jqGrid向服务器传递的参数是一个名字叫做filters的json字符串。类似于如下的形式:

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参数的解析。

json-lib包不仅提供了把Bean或容器类List、Map等转换为json格式数据的方法,而且提供了把json格式数据转换为容器类或者Bean类对象的方法。

为了方便转换,我们这里定义了两个Transfer Object对象,分别是JqGridSearchTo对象以及JqGridSearchDetailTo对象。

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中的查询条件设计的,相对非常简单:

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 !

以上部分代码存在一些隐患,请勿用于您的正式环境!

你可能感兴趣的:(jqGrid的多字段查询)