`
yiyu
  • 浏览: 183215 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

jqGrid <-- json --> spring,hibernate之服务器端分页,排序

    博客分类:
  • java
阅读更多
最近做了一个以jqGrid实现的数据表格,与服务器端(spring + hibernate)以json格式交换数据,分页
和排序都在服务器端实现,现总结如下:

操作页面是这样的:



用户输入查询信息,按“检索”按钮,返回查询结果,表格可以翻页,排序。

当把jqGrid的属性datatype定义为function时,表格需要获取数据时(翻页,排序等),jqGrid就会调用
这个function,通过这种机制,就可以实现服务器端分页、排序。需要注意的是,这个function需要读取
数据并显式地调用addJSONData,addXMLData等去刷新表格,详情可以参看:
http://www.trirand.com/jqgridwiki/doku.php?id=wiki:retrieving_data#function

这个函数有一个参数,关于参数的定义我没有找到,但用firebug之类的工具可以看出包括如下的属性:
_search : (不清楚)
nd : (不清楚)
page : 当前页
rows : 每页记录数
sidx : sort index,排序字段名
sord : sort direction,排序方式:asc, desc

这样一来,我们就可以把这些数据发送到服务器端进行分页和排序。

以下是页面的html代码:
	<table width="95%">
		<tr>
			<td>
				<table>
					<tr>
						<td>
							<form id="frmSearchCustomer">
								<table>
									<tr>
										<td>
											名称:<input type="text" name="name" />
											アドレス:<input type="text" name="addr" />
										</td>
									</tr>
									<tr>
										<td>
											担当者:<input type="text" name="dandang" />
										</td>
									</tr>
								</table>
							</form>
						</td>
					</tr>
					<tr>
						<td>
							<button id="search">检索</button>
							<button id="clear">清除条件</button>
						</td>
					</tr>
				</table>
			</td>
		</tr>
		<tr>
			<td>
				<table id="list"></table>
				<div id="pager"></div> 
			</td>
		</tr>
	</table>


以下是jqGrid初始化的代码:

	$("#list").jqGrid({
		datatype : function(postdata) {
			postdata = mergeObject(jsonCondition, postdata);
			
			jQuery.ajax({
				type : 'POST',
				contentType : 'application/json',
				url : ROOT_PATH + '/customer/search.do',
				data : JSON.stringify(postdata),
				dataType : 'json',
				success : function(resp) {
					if (resp.successed) {
						var thegrid = jQuery("#list")[0];
						thegrid.addJSONData(resp.returnObject);
					} else {
						alert(resp.errors[0].message);
					}
				},
				error : ajaxFailed
			});
		},
		height : '100%',
		rowNum : '10',
		jsonReader : {
			repeatitems: false
		},
		colNames : ['顧客番号', '名称', 'アドレス', '担当者', '携帯', '電話①', '電話②'],
		colModel : [ 
				   {name:'id', index:'id', width:80}, 
				   {name:'name', index:'name', width:256},
				   {name:'addr', index:'addr', width:256},
				   {name:'dandang', index:'dandang', width:64},
				   {name:'mobile', index:'mobile', width:128},
				   {name:'phone1', index:'phone1', width:128},
				   {name:'phone2', index:'phone2', width:128},
				 ],
		pager : '#pager'
	});


其中关键就是datatype为一function,在这个function中通过jQuery.ajax发送一个请求,获取数据,然后通过
addJSONData刷新表格数据。发送的数据包括postdata和用户输入的查询条件,其中postdata是jqGrid传递过来
的包含分页、排序信息的对象,jsonCondition是“检索”按钮中生成的包含查询条件的对象。
检索按钮中的处理如下:

	var jsonCondition = {};
	
	function search() {
		jsonCondition = array2Json(jQuery("#frmSearchCustomer").serializeArray());
		jQuery("#list").trigger("reloadGrid");
	}

其中array2Json是从网上找来的把jQuery的serializeArray生成的数组转成json的函数,我以前的文章里有,这里
就不重复了。

mergeObject是一个我自己写的拷贝一个对象的属性到另一对象的函数:
	function mergeObject(src, dest) {
		var i;
		for(i in src) {
			dest[i]=src[i];
		}
		return dest;
	}


下面说下服务器端。
我用的spring的controller是直接接受json数据并以json格式返回数据的,这部分是延续以前的做法的,可以参见
我以前的文章:
jquery(1.3.2)<--json-->spring(3.0)
jquery<--json-->spring(3.0)之后台校验

我定义了一个对应jqGrid的postdata的类:
	public class JQGridRequest {
		private String _search;
		private String nd;
		private int page;
		private int rows;
		private String sidx;
		private String sord;
		
		...
	}


对于不同的查询页面,可以扩展这个类,定义包含该页面查询条件的类,本例中我定义了这样的类:
	public class CustomerSearchInfo extends JQGridRequest {
		private String name;
		private String addr;
		private String dandang;
		
		...
	}


Controller的定义如下,其中接受的参数就是上面所说的CustomerSearchInfo这个类:
@Controller
@RequestMapping("/customer")
public class CustomerController extends JSONController {
	private CustomerService customerService;
	
	...
	
	@RequestMapping(value = "/search", method = RequestMethod.POST)
	@ResponseBody
	public JSONResponse search(@RequestBody CustomerSearchInfo searchInfo) {
		JQGridResponse data = customerService.search(searchInfo);
		return this.successed(data);
	}
}


jqGrid对于json数据是有格式要求的(这个格式可以自定义),详情可以参见
http://www.trirand.com/jqgridwiki/doku.php?id=wiki:retrieving_data#json_data
当repeatitems为false时默认是这样的:
	{ 
	  "total": "xxx", //总页数
	  "page": "yyy",  //当前页
	  "records": "zzz", //本次查询的记录数
	  "rows" : [
		{"id" :"1", "name" : "xxxx", "addr" : "xxxx", ...},
		{"id" :"2", "name" : "xxxx", "addr" : "xxxx", ...},
		  ...
	  ]
	}


所以我还为服务器端的返回数据定义了一个类:
	public class JQGridResponse {
		private int total; //total pages
		private int page; //current page
		private int records; //total records
		private ArrayList<Object> rows;
		
		...
	}


customerService.search(searchInfo)返回的就是这样一个类。service的代码如下:
其中计算了总页数,当前页,记录数,同时通过相应的setter方法进行赋值。

	@Override
	@Transactional
	public JQGridResponse search(CustomerSearchInfo searchInfo) {
		JQGridResponse response = new JQGridResponse();

		int count = baseInfoDao.count(searchInfo);
		
		double dCount = (double)count;
		double dRows = (double)searchInfo.getRows();
		int total = (int)Math.ceil(dCount / dRows); //total page
		response.setTotal(total);
		int curPage = Math.min(total, searchInfo.getPage()); //current page
		response.setPage(curPage);
		searchInfo.setPage(curPage); //这是为了在dao中查询用的
		
		ArrayList<Object> customers = new ArrayList<Object>();
		//检索符合条件的数据(略)
		...
		
		response.setRecords(customers.size());
		response.setRows(customers);
		
		return response;
	}


在dao层,就是利用hibernate的setFirstResult和setMaxResults读取当前页的记录,需要注意
的是,对于符合条件的总记录数需要使用Projections.rowCount()获得,所以我做了两个方法
search和count,前者是取得本次查询当前页的数据,后者是本次查询的记录总数,这两者的
查询条件是一样的,但前者需要加上排序信息,并且指定仅返回当前页的记录数,后者仅获取
记录条数(其实就是select count(*)),代码片段如下:
public class CustomerBaseInfoDaoImpl implements CustomerBaseInfoDao {
	private SessionFactory sessionFactory;

	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}
	
	...
	
	@Override
	public List<CustomerBaseInfo> search(CustomerSearchInfo searchInfo) {
		Session session = sessionFactory.getCurrentSession();
		Criteria c = getSearchCriteria(session, searchInfo);
		
		//排序
		String sortIdx = searchInfo.getSidx();
		if (sortIdx.length() > 0) {
			if ("asc".equalsIgnoreCase(searchInfo.getSord())) {
				c.addOrder(Order.asc(sortIdx));
			} else {
				c.addOrder(Order.desc(sortIdx));
			}
		}
		
		c.setFirstResult((searchInfo.getPage() - 1) * searchInfo.getRows());
		c.setMaxResults(searchInfo.getRows());

		return (List<CustomerBaseInfo>)c.list();
	}

	@Override
	public int count(CustomerSearchInfo searchInfo) {
		Session session = sessionFactory.getCurrentSession();
		Criteria c = getSearchCriteria(session, searchInfo);
		
		c.setProjection(Projections.rowCount());

		return ((Integer)c.list().get(0)).intValue();
	}
	
	private Criteria getSearchCriteria(Session session, CustomerSearchInfo searchInfo) {
		Criteria c = session.createCriteria(CustomerBaseInfo.class);
		
		//检索条件
		String name =  searchInfo.getName();
		if (name != null && name.trim().length() > 0) {
			c.add(Restrictions.ilike("name", "%" + name + "%"));
		}
		
		String addr = searchInfo.getAddr();
		if (addr != null && addr.trim().length() > 0) {
			c.add(Restrictions.ilike("addr", "%" + addr + "%"));
		}
		
		String dandang = searchInfo.getDandang();
		if (dandang != null && dandang.trim().length() > 0) {
			c.add(Restrictions.ilike("dandang", "%" + dandang + "%"));
		}
		
		return c;
	}

}
  • 大小: 49.2 KB
分享到:
评论
1 楼 lijunwyf41 2014-05-21  
nd:"nd", // 表示已经发送请求的次数的参数名称

相关推荐

    JqGrid 纯Json自带分页功能

    Jqgrid json 自身带的分页功能, 为了减轻数据库压力和提高加载速度,生成了纯JSON文件,想在本地自动分页,找了N多API均没有详细的介绍,最终摸索出来一个属性本身就自带分页功能,与大家分享

    Jqgrid demo-史上最强大,没有之一

    Jqgrid demo-史上最强大,没有之一, 为了大家能够更好的学习和使用Jqgrid网格插件,我决定用Strtus2+Spring+hibernate+Jquery+Jqgrid实现一个Jqgrid网格插件的demo。当然官方网站上面已经有了PHP版本和ASP.NET版本...

    jqGrid 做的表格分页

    &lt;script type="text/javascript" src="js/jquery.jqGrid.min.js"&gt;&lt;/script&gt; &lt;script type="text/javascript" src="js/jquery.tablednd.js"&gt;&lt;/script&gt; &lt;script type="text/javascript" src="js/jquery.contextmenu.js...

    jquery.jqGrid-4.4.3

    jquery.jqGrid-4.4.3,用于web页面的列表分页显示

    jqgrid方法-中文 (2).docx

    jqgrid方法-中文 (2).docxjqgrid方法-中文 (2).docx

    jqGrid插件--JQuery表格插件

    jqGrid是一个非常好用的免费开源Grid组件,功能强大,适用于各种表格操作,数据管理。作为jquery插件,jqGrid使用方便,简介,美观。

    Spring MVC 分页组件和JqGrid导出

    Spring MVC 分页组件和JqGrid导出 分页组件为通用 比较全面 jqGrid 实现导出excel功能 及行添加按钮操作

    jquery.jqGrid-3.8.2.zip

    jquery.jqGrid-3.8.2.zipjquery.jqGrid-3.8.2.zipjquery.jqGrid-3.8.2.zipjquery.jqGrid-3.8.2.zipjquery.jqGrid-3.8.2.zipjquery.jqGrid-3.8.2.zip

    jquery.jqGrid-4.5.2.zip

    jquery.jqGrid-4.5.2.zip 官方资源文件

    jqGrid4.8.2 jqgrid_demo40

    jquery.jqGrid-4.8.2(jquery表格插件).zip----------jqGrid4.8.2包,官网下载的,原封不动的在这里。 jqgrid_demo40-----可用的-使用方法请查看README文件. jqgrid_3.6.5_API_en.chm------附加放在这里的其它资料...

    jqgrid分页参数

    现在把找好的分页参数跟大家分享下

    jqgrid jquery-ui-1.8.17.custom.css

    jqgrid jquey 样式 让表格变得更漂亮

    JqGrid分页

    JqGrid EF分页

    jquery.jqGrid-4.3.1+jquery-ui-1.8.17.rar

    jquery.jqGrid-4.3.1+jquery-ui-1.8.17.rar

    jquery.jqGrid-4.3.3

    jqGrid 是一个用来显示网格数据的jQuery插件,文档比较全面,附带中文版本。 主要特点: -Full control with JavaScript API -Data returned from the server is XML -Simple configuration -Ability to load big ...

    jqGrid-wiki版手册

    jqGrid-wiki版手册

    jqGrid demo in JSP Struts2 & Hibernate 新版myeclise for Spring 10.0

    有人问到没有spring,由于主要是演示jqGrid和jQuery的AJAX功能,所以没有加上spring框架, 如有需要的请留言. jqGrid 演示最新版: 用到的组件: 1.jqgrid 4.4, 2.jQuery 1.8.0, jQuery-ui 1.8.23 3.html5.0

    jqGrid-master

    jqGrid-master最新版,从英文站点下载而来,方便各位下载

    jquery.jqGrid-4.1.1.zip

    jquery.jqGrid-4.1.1.zipjquery.jqGrid-4.1.1.zipjquery.jqGrid-4.1.1.zip

    jqGrid-3.2.zip

    jqGrid-3.2 jqgriddocs.pdf jquery.jqGrid.js

Global site tag (gtag.js) - Google Analytics