- 浏览: 67093 次
文章分类
最新评论
jqGrid与Struts2的结合应用(七) —— 浅谈排序
终于讲到排序了,这一部分应该说还是比较好理解的。
jqGrid通过colModel选项中的sortable来控制是否可以以某列的值排序。sortable的默认值是true,当设为false时,即此列不能用于排序。
- $(function(){
- $("#gridTable").jqGrid({
- ...
- colModel:[
- {name:"id",index:"id",label:"编码",width:40},
- {name:"lastName",index:"lastName",label:"姓",width:80},
- {name:"firstName",index:"firstName",label:"名",width:80},
- {name:"email",index:"email",label:"电子邮箱",width:160,sortable:false},
- {name:"telNo",index:"telNo",label:"电话",width:120,sortable:false}
- ],
- ...
- });
- });
当点击sortable为true的列首时,jqGrid会向Server发送排序请求,例如:
http://localhost:8085/Hare/jqGridTest/jqGrid05.action?search=false&nd=1279006749246&rows=15&page=3&sidx=firstName&sord=asc
注:其中sord和sidx参数名都是在jqGrid的prmNames选项中设定的(可参考本系列文章的第一篇)。而sidx参数的值即各列的colModel的index选项值。(在查询和排序时,发送的关于列的参数都是基于colModel的index属性的)
后面的事情就交给服务器端的Action来处理了,还拿我们的Contact联系人列表为例。
既然我们可能会分别使用不同的字段来排序,那么就必须为Contact提供不同的Comparator来简化比较操作。因此我写了一个针对Contact的Comparator的工厂类,用来根据不同的字段提供不同的Comparator。
ContactComparatorFactory的代码:
- packagecn.gengv.struts2ex.jqGrid;
- importjava.text.Collator;
- importjava.util.Comparator;
- importcom.byzl.hare.model.Contact;
- publicclassContactComparatorFactory{
- privatestaticCollatorcollator_Chinese=Collator.getInstance(java.util.Locale.CHINA);
- privatefinalstaticComparator<Contact>idComparator=newIdComparator();
- privatefinalstaticComparator<Contact>firstNameComparator=newFirstNameComparator();
- privatefinalstaticComparator<Contact>lastNameComparator=newLastNameComparator();
- privatefinalstaticComparator<Contact>fullNameComparator=newFullNameComparator();
- privatefinalstaticComparator<Contact>idCardNoNoComparator=newIdCardNoComparator();
- privatefinalstaticComparator<Contact>nationalityComparator=newNationalityComparator();
- publicstaticComparator<Contact>getComparator(StringcompareType){
- if("id".equalsIgnoreCase(compareType)){
- returnidComparator;
- }elseif("firstName".equalsIgnoreCase(compareType)){
- returnfirstNameComparator;
- }elseif("lastName".equalsIgnoreCase(compareType)){
- returnlastNameComparator;
- }elseif("fullName".equalsIgnoreCase(compareType)){
- returnfullNameComparator;
- }elseif("idCardNoNo".equalsIgnoreCase(compareType)){
- returnidCardNoNoComparator;
- }elseif("nationality".equalsIgnoreCase(compareType)){
- returnnationalityComparator;
- }else{
- returnnull;
- }
- }
- publicstaticclassIdComparatorimplementsComparator<Contact>{
- publicintcompare(Contactc1,Contactc2){
- if(c1==null&&c2==null){
- return0;
- }elseif(c1==null&&c2!=null){
- return-1;
- }elseif(c1!=null&&c2==null){
- return1;
- }else{
- intid1=c1.getId();
- intid2=c2.getId();
- returnid1==id2?0:(id1<id2?-1:1);
- }
- }
- }
- publicstaticclassFirstNameComparatorimplementsComparator<Contact>{
- publicintcompare(Contactc1,Contactc2){
- if(c1==null&&c2==null){
- return0;
- }elseif(c1==null&&c2!=null){
- return-1;
- }elseif(c1!=null&&c2==null){
- return1;
- }else{
- Strings1=c1.getFirstName();
- Strings2=c2.getFirstName();
- if(s1==null&&s2==null){
- return0;
- }elseif(s1==null&&s2!=null){
- return-1;
- }elseif(s1!=null&&s2==null){
- return1;
- }else{
- returncollator_Chinese.compare(s1,s2);
- }
- }
- }
- }
- publicstaticclassLastNameComparatorimplementsComparator<Contact>{
- publicintcompare(Contactc1,Contactc2){
- if(c1==null&&c2==null){
- return0;
- }elseif(c1==null&&c2!=null){
- return-1;
- }elseif(c1!=null&&c2==null){
- return1;
- }else{
- Strings1=c1.getLastName();
- Strings2=c2.getLastName();
- if(s1==null&&s2==null){
- return0;
- }elseif(s1==null&&s2!=null){
- return-1;
- }elseif(s1!=null&&s2==null){
- return1;
- }else{
- returncollator_Chinese.compare(s1,s2);
- }
- }
- }
- }
- publicstaticclassFullNameComparatorimplementsComparator<Contact>{
- publicintcompare(Contactc1,Contactc2){
- if(c1==null&&c2==null){
- return0;
- }elseif(c1==null&&c2!=null){
- return-1;
- }elseif(c1!=null&&c2==null){
- return1;
- }else{
- Strings1=c1.getFullName();
- Strings2=c2.getFullName();
- if(s1==null&&s2==null){
- return0;
- }elseif(s1==null&&s2!=null){
- return-1;
- }elseif(s1!=null&&s2==null){
- return1;
- }else{
- returncollator_Chinese.compare(s1,s2);
- }
- }
- }
- }
- publicstaticclassIdCardNoComparatorimplementsComparator<Contact>{
- publicintcompare(Contactc1,Contactc2){
- if(c1==null&&c2==null){
- return0;
- }elseif(c1==null&&c2!=null){
- return-1;
- }elseif(c1!=null&&c2==null){
- return1;
- }else{
- Strings1=c1.getIdCardNo();
- Strings2=c2.getIdCardNo();
- if(s1==null&&s2==null){
- return0;
- }elseif(s1==null&&s2!=null){
- return-1;
- }elseif(s1!=null&&s2==null){
- return1;
- }else{
- returns1.compareToIgnoreCase(s2);
- }
- }
- }
- }
- publicstaticclassNationalityComparatorimplementsComparator<Contact>{
- publicintcompare(Contactc1,Contactc2){
- if(c1==null&&c2==null){
- return0;
- }elseif(c1==null&&c2!=null){
- return-1;
- }elseif(c1!=null&&c2==null){
- return1;
- }else{
- Strings1=c1.getNationality();
- Strings2=c2.getNationality();
- if(s1==null&&s2==null){
- return0;
- }elseif(s1==null&&s2!=null){
- return-1;
- }elseif(s1!=null&&s2==null){
- return1;
- }else{
- returncollator_Chinese.compare(s1,s2);
- }
- }
- }
- }
- }
然后再来看JqGridBaseAction,其中添加了一个抽象方法,用来将数据结果进行排序。
- packagecn.gengv.struts2ex.jqGrid;
- //import...
- @SuppressWarnings("serial")
- publicabstractclassJqGridBaseAction<T>extendsActionSupport{
- ...
- //(1)添加排序方法
- publicabstractvoidsortResults(List<T>results,Stringfield,Stringorder);
- publicStringrefreshGridModel(){
- try{
- List<Criterion>criteria=Collections.emptyList();
- if(search==true){
- criteria=newArrayList<Criterion>();
- if(filters!=null&&filters.length()>0){
- criteria.addAll(this.generateSearchCriteriaFromFilters(filters));
- }
- Criterioncriterion=this.generateSearchCriterion(searchField,searchString,searchOper);
- if(criterion!=null){
- criteria.add(criterion);
- }
- }
- List<T>results=Collections.emptyList();
- intfrom=rows*(page-1);
- intlength=rows;
- if(loadonce){
- from=0;
- length=100;
- }
- if(!criteria.isEmpty()){
- record=this.getResultSize(criteria);
- results=this.listResults(criteria,from,length);
- }else{
- record=this.getResultSize();
- results=this.listResults(from,length);
- }
- //(2)将结果排序
- if(sidx!=null&&sord!=null){
- sortResults(results,sidx,sord);
- }
- this.setGridModel(results);
- total=(int)Math.ceil((double)record/(double)rows);
- returnSUCCESS;
- }catch(Exceptione){
- e.printStackTrace();
- this.addActionError(e.getMessage());
- returnERROR;
- }
- }
- ...
- }
而在ListContactsAction中提供了方法实现:
- packagecn.gengv.struts2ex.jqGrid;
- importjava.util.Collections;
- importjava.util.Comparator;
- importjava.util.List;
- importcom.byzl.hare.dao.impl.Criterion;
- importcom.byzl.hare.model.Contact;
- importcom.byzl.hare.service.ContactService;
- @SuppressWarnings("serial")
- publicclassListContactsActionextendsJqGridBaseAction<Contact>{
- ...
- @Override
- publicvoidsortResults(List<Contact>results,Stringfield,Stringorder){
- //(1)根据field获得对应的Comparator
- Comparator<Contact>comparator=ContactComparatorFactory.getComparator(field);
- if(comparator!=null){
- //(2)使用Comparator排序
- Collections.sort(results,comparator);
- //(3)如果需要的排序顺序为desc,则颠倒顺序
- if("desc".equals(order)){
- Collections.reverse(results);
- }
- }
- }
- ...
- }
不过这个例子存在一定的局限性,即只能将当前页中的数据根据某列进行排序;而不能跨页间进行数据排序。之所以存在这种局限,也是源于实际应用中的客观限制。还以这个例子来说,数据库里总共模拟了两万多条数据记录。如果每次要将这些记录进行排里的话,除非有数据库索引支持,否则所要消耗的时间也是相当客观的,对于用户体验来说,几乎就是灾难。如果数据量更多的话,结果可想而知。
因此,我们应该换一个角度来看这个问题,用户之所以使用排序,更多的目的还是在于查找数据方便,既然我们可以提供条件查询(尤其是复杂条件查询),那么用户对于排序的需求也就不会那么迫切了。同时也可以体会到,排序更多地应用在少量数据的场合下。
终于讲到排序了,这一部分应该说还是比较好理解的。
jqGrid通过colModel选项中的sortable来控制是否可以以某列的值排序。sortable的默认值是true,当设为false时,即此列不能用于排序。
- $(function(){
- $("#gridTable").jqGrid({
- ...
- colModel:[
- {name:"id",index:"id",label:"编码",width:40},
- {name:"lastName",index:"lastName",label:"姓",width:80},
- {name:"firstName",index:"firstName",label:"名",width:80},
- {name:"email",index:"email",label:"电子邮箱",width:160,sortable:false},
- {name:"telNo",index:"telNo",label:"电话",width:120,sortable:false}
- ],
- ...
- });
- });
当点击sortable为true的列首时,jqGrid会向Server发送排序请求,例如:
http://localhost:8085/Hare/jqGridTest/jqGrid05.action?search=false&nd=1279006749246&rows=15&page=3&sidx=firstName&sord=asc
注:其中sord和sidx参数名都是在jqGrid的prmNames选项中设定的(可参考本系列文章的第一篇)。而sidx参数的值即各列的colModel的index选项值。(在查询和排序时,发送的关于列的参数都是基于colModel的index属性的)
后面的事情就交给服务器端的Action来处理了,还拿我们的Contact联系人列表为例。
既然我们可能会分别使用不同的字段来排序,那么就必须为Contact提供不同的Comparator来简化比较操作。因此我写了一个针对Contact的Comparator的工厂类,用来根据不同的字段提供不同的Comparator。
ContactComparatorFactory的代码:
- packagecn.gengv.struts2ex.jqGrid;
- importjava.text.Collator;
- importjava.util.Comparator;
- importcom.byzl.hare.model.Contact;
- publicclassContactComparatorFactory{
- privatestaticCollatorcollator_Chinese=Collator.getInstance(java.util.Locale.CHINA);
- privatefinalstaticComparator<Contact>idComparator=newIdComparator();
- privatefinalstaticComparator<Contact>firstNameComparator=newFirstNameComparator();
- privatefinalstaticComparator<Contact>lastNameComparator=newLastNameComparator();
- privatefinalstaticComparator<Contact>fullNameComparator=newFullNameComparator();
- privatefinalstaticComparator<Contact>idCardNoNoComparator=newIdCardNoComparator();
- privatefinalstaticComparator<Contact>nationalityComparator=newNationalityComparator();
- publicstaticComparator<Contact>getComparator(StringcompareType){
- if("id".equalsIgnoreCase(compareType)){
- returnidComparator;
- }elseif("firstName".equalsIgnoreCase(compareType)){
- returnfirstNameComparator;
- }elseif("lastName".equalsIgnoreCase(compareType)){
- returnlastNameComparator;
- }elseif("fullName".equalsIgnoreCase(compareType)){
- returnfullNameComparator;
- }elseif("idCardNoNo".equalsIgnoreCase(compareType)){
- returnidCardNoNoComparator;
- }elseif("nationality".equalsIgnoreCase(compareType)){
- returnnationalityComparator;
- }else{
- returnnull;
- }
- }
- publicstaticclassIdComparatorimplementsComparator<Contact>{
- publicintcompare(Contactc1,Contactc2){
- if(c1==null&&c2==null){
- return0;
- }elseif(c1==null&&c2!=null){
- return-1;
- }elseif(c1!=null&&c2==null){
- return1;
- }else{
- intid1=c1.getId();
- intid2=c2.getId();
- returnid1==id2?0:(id1<id2?-1:1);
- }
- }
- }
- publicstaticclassFirstNameComparatorimplementsComparator<Contact>{
- publicintcompare(Contactc1,Contactc2){
- if(c1==null&&c2==null){
- return0;
- }elseif(c1==null&&c2!=null){
- return-1;
- }elseif(c1!=null&&c2==null){
- return1;
- }else{
- Strings1=c1.getFirstName();
- Strings2=c2.getFirstName();
- if(s1==null&&s2==null){
- return0;
- }elseif(s1==null&&s2!=null){
- return-1;
- }elseif(s1!=null&&s2==null){
- return1;
- }else{
- returncollator_Chinese.compare(s1,s2);
- }
- }
- }
- }
- publicstaticclassLastNameComparatorimplementsComparator<Contact>{
- publicintcompare(Contactc1,Contactc2){
- if(c1==null&&c2==null){
- return0;
- }elseif(c1==null&&c2!=null){
- return-1;
- }elseif(c1!=null&&c2==null){
- return1;
- }else{
- Strings1=c1.getLastName();
- Strings2=c2.getLastName();
- if(s1==null&&s2==null){
- return0;
- }elseif(s1==null&&s2!=null){
- return-1;
- }elseif(s1!=null&&s2==null){
- return1;
- }else{
- returncollator_Chinese.compare(s1,s2);
- }
- }
- }
- }
- publicstaticclassFullNameComparatorimplementsComparator<Contact>{
- publicintcompare(Contactc1,Contactc2){
- if(c1==null&&c2==null){
- return0;
- }elseif(c1==null&&c2!=null){
- return-1;
- }elseif(c1!=null&&c2==null){
- return1;
- }else{
- Strings1=c1.getFullName();
- Strings2=c2.getFullName();
- if(s1==null&&s2==null){
- return0;
- }elseif(s1==null&&s2!=null){
- return-1;
- }elseif(s1!=null&&s2==null){
- return1;
- }else{
- returncollator_Chinese.compare(s1,s2);
- }
- }
- }
- }
- publicstaticclassIdCardNoComparatorimplementsComparator<Contact>{
- publicintcompare(Contactc1,Contactc2){
- if(c1==null&&c2==null){
- return0;
- }elseif(c1==null&&c2!=null){
- return-1;
- }elseif(c1!=null&&c2==null){
- return1;
- }else{
- Strings1=c1.getIdCardNo();
- Strings2=c2.getIdCardNo();
- if(s1==null&&s2==null){
- return0;
- }elseif(s1==null&&s2!=null){
- return-1;
- }elseif(s1!=null&&s2==null){
- return1;
- }else{
- returns1.compareToIgnoreCase(s2);
- }
- }
- }
- }
- publicstaticclassNationalityComparatorimplementsComparator<Contact>{
- publicintcompare(Contactc1,Contactc2){
- if(c1==null&&c2==null){
- return0;
- }elseif(c1==null&&c2!=null){
- return-1;
- }elseif(c1!=null&&c2==null){
- return1;
- }else{
- Strings1=c1.getNationality();
- Strings2=c2.getNationality();
- if(s1==null&&s2==null){
- return0;
- }elseif(s1==null&&s2!=null){
- return-1;
- }elseif(s1!=null&&s2==null){
- return1;
- }else{
- returncollator_Chinese.compare(s1,s2);
- }
- }
- }
- }
- }
然后再来看JqGridBaseAction,其中添加了一个抽象方法,用来将数据结果进行排序。
- packagecn.gengv.struts2ex.jqGrid;
- //import...
- @SuppressWarnings("serial")
- publicabstractclassJqGridBaseAction<T>extendsActionSupport{
- ...
- //(1)添加排序方法
- publicabstractvoidsortResults(List<T>results,Stringfield,Stringorder);
- publicStringrefreshGridModel(){
- try{
- List<Criterion>criteria=Collections.emptyList();
- if(search==true){
- criteria=newArrayList<Criterion>();
- if(filters!=null&&filters.length()>0){
- criteria.addAll(this.generateSearchCriteriaFromFilters(filters));
- }
- Criterioncriterion=this.generateSearchCriterion(searchField,searchString,searchOper);
- if(criterion!=null){
- criteria.add(criterion);
- }
- }
- List<T>results=Collections.emptyList();
- intfrom=rows*(page-1);
- intlength=rows;
- if(loadonce){
- from=0;
- length=100;
- }
- if(!criteria.isEmpty()){
- record=this.getResultSize(criteria);
- results=this.listResults(criteria,from,length);
- }else{
- record=this.getResultSize();
- results=this.listResults(from,length);
- }
- //(2)将结果排序
- if(sidx!=null&&sord!=null){
- sortResults(results,sidx,sord);
- }
- this.setGridModel(results);
- total=(int)Math.ceil((double)record/(double)rows);
- returnSUCCESS;
- }catch(Exceptione){
- e.printStackTrace();
- this.addActionError(e.getMessage());
- returnERROR;
- }
- }
- ...
- }
而在ListContactsAction中提供了方法实现:
- packagecn.gengv.struts2ex.jqGrid;
- importjava.util.Collections;
- importjava.util.Comparator;
- importjava.util.List;
- importcom.byzl.hare.dao.impl.Criterion;
- importcom.byzl.hare.model.Contact;
- importcom.byzl.hare.service.ContactService;
- @SuppressWarnings("serial")
- publicclassListContactsActionextendsJqGridBaseAction<Contact>{
- ...
- @Override
- publicvoidsortResults(List<Contact>results,Stringfield,Stringorder){
- //(1)根据field获得对应的Comparator
- Comparator<Contact>comparator=ContactComparatorFactory.getComparator(field);
- if(comparator!=null){
- //(2)使用Comparator排序
- Collections.sort(results,comparator);
- //(3)如果需要的排序顺序为desc,则颠倒顺序
- if("desc".equals(order)){
- Collections.reverse(results);
- }
- }
- }
- ...
- }
不过这个例子存在一定的局限性,即只能将当前页中的数据根据某列进行排序;而不能跨页间进行数据排序。之所以存在这种局限,也是源于实际应用中的客观限制。还以这个例子来说,数据库里总共模拟了两万多条数据记录。如果每次要将这些记录进行排里的话,除非有数据库索引支持,否则所要消耗的时间也是相当客观的,对于用户体验来说,几乎就是灾难。如果数据量更多的话,结果可想而知。
因此,我们应该换一个角度来看这个问题,用户之所以使用排序,更多的目的还是在于查找数据方便,既然我们可以提供条件查询(尤其是复杂条件查询),那么用户对于排序的需求也就不会那么迫切了。同时也可以体会到,排序更多地应用在少量数据的场合下。
相关推荐
jqgrid与struts2结合的例子
自己搜集的jqGrid与Struts2的结合应用的方法
jqgrid+struts结合简单显示示例
jqGrid与Struts2 详细文档jqgrid 3.8详细文档 翻页,查询排序。
jqgrid+struts2+jdbc实现的增删改查
jqgrid+struts2+ibatis+oracle增删改查
struts配置文件和hibernate的配置文件都在src目录下 4.这就是jqGrid最简单的演示,没有加入任何其它功能, Good Luck! 有人问到没有spring,由于主要是演示jqGrid和jQuery的AJAX功能,所以没有加上spring框架, 如有...
jqGrid 、jqPlugin、Struts2结合例子
jqGrid可以结合fancybox等插件完成超酷的弹出层效果,通过与php后台交互,可以轻松完成数据的添加与详情查看,而这个过程完全是一个ajax异步通信过程,是一个非常友好的富客户端应用
jqGrid详解及高级应用
Struts2 和 hibernate 演示 jqGrid, 使用Action中的 代码可以容易的把jqGrid 用于servlet或纯jsp. Struts 2.16, jqGrid 3.5b, hibernate 3.2 annotation 由于我的上传权限为20M,而我上传上的包括所有的源代码和支持...
jqGrid demo in Struts2 & Hibernate war file part2
jqGrid demo in Struts2 & Hibernate war file (SQL Script included in WEB-INF\classes)
jqGrid 中的锁定固定的列并且关于jqGrid 中的一些排序的实现细节
一个jqGrid结合struts2的实例,实现了基本的增删改查
Java版本的JQGrid分页,是使用struts2框架
jqGrid结合servlet的范例 jqGrid结合Struts2的范例
jqGrid demo in Struts2 & Hibernate源码压缩包第二部分(part2) 这只是源码包的第二部分(part2),请同时下载其它两部分,part3 and part1
jqGrid 学习 原理 2 jqGrid 学习之 皮肤 2 jqGrid 学习 2 jQuery 学习之:jqGrid 表格插件 参数配置 4 jqGrid 学习 自定义搜索 14 jqGrid 学习 搜索工具栏 16 jqGrid 学习 搜索 17 jqGrid 学习 自定义格式化类型 19 ...
jqGrid demo in Struts2 & Hibernate所有源代码,包括MyEclipse工程(myeclipse 7.5), 运行时jar包,MySQL数据库脚本,在hibernate中使用的数据库用户名密码为root/root,如果你的mysql密码不同请在src\hibernate.cfg...