jqGrid与Struts2的结合应用(七) —— 浅谈排序

原文地址:http://blog.csdn.net/gengv/article/details/5732698

如不能转载,请联系博主,我马上删除。

终于讲到排序了,这一部分应该说还是比较好理解的。

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的代码:

package cn.gengv.struts2ex.jqGrid;  
import java.text.Collator;  
import java.util.Comparator;  
import com.byzl.hare.model.Contact;  
public class ContactComparatorFactory {  
    private static Collator collator_Chinese = Collator.getInstance(java.util.Locale.CHINA);  
    private final static Comparator<Contact> idComparator = new IdComparator();  
    private final static Comparator<Contact> firstNameComparator = new FirstNameComparator();  
    private final static Comparator<Contact> lastNameComparator = new LastNameComparator();  
    private final static Comparator<Contact> fullNameComparator = new FullNameComparator();  
    private final static Comparator<Contact> idCardNoNoComparator = new IdCardNoComparator();  
    private final static Comparator<Contact> nationalityComparator = new NationalityComparator();  
      
      
    public static Comparator<Contact> getComparator(String compareType) {  
        if ("id".equalsIgnoreCase(compareType)) {  
            return idComparator;  
        } else if ("firstName".equalsIgnoreCase(compareType)) {  
            return firstNameComparator;  
        } else if ("lastName".equalsIgnoreCase(compareType)) {  
            return lastNameComparator;  
        } else if ("fullName".equalsIgnoreCase(compareType)) {  
            return fullNameComparator;  
        } else if ("idCardNoNo".equalsIgnoreCase(compareType)) {  
            return idCardNoNoComparator;  
        } else if ("nationality".equalsIgnoreCase(compareType)) {  
            return nationalityComparator;  
        } else {  
            return null;  
        }  
    }  
      
    public static class IdComparator implements Comparator<Contact> {  
        public int compare(Contact c1, Contact c2) {  
            if (c1 == null && c2 == null) {  
                return 0;  
            } else if (c1 == null && c2 != null) {  
                return -1;  
            } else if (c1 != null && c2 == null) {  
                return 1;  
            } else {  
                int id1 = c1.getId();  
                int id2 = c2.getId();  
                return id1 == id2 ? 0 : (id1 < id2 ? -1 : 1);  
            }  
        }  
    }  
      
    public static class FirstNameComparator implements Comparator<Contact> {  
        public int compare(Contact c1, Contact c2) {  
            if (c1 == null && c2 == null) {  
                return 0;  
            } else if (c1 == null && c2 != null) {  
                return -1;  
            } else if (c1 != null && c2 == null) {  
                return 1;  
            } else {  
                String s1 = c1.getFirstName();  
                String s2 = c2.getFirstName();  
                  
                if (s1 == null && s2 == null) {  
                    return 0;  
                } else if (s1 == null && s2 != null) {  
                    return -1;  
                } else if (s1 != null && s2 == null) {  
                    return 1;  
                } else {  
                    return collator_Chinese.compare(s1, s2);  
                }  
            }  
        }  
    }  
      
    public static class LastNameComparator implements Comparator<Contact> {  
        public int compare(Contact c1, Contact c2) {  
            if (c1 == null && c2 == null) {  
                return 0;  
            } else if (c1 == null && c2 != null) {  
                return -1;  
            } else if (c1 != null && c2 == null) {  
                return 1;  
            } else {  
                String s1 = c1.getLastName();  
                String s2 = c2.getLastName();  
                  
                if (s1 == null && s2 == null) {  
                    return 0;  
                } else if (s1 == null && s2 != null) {  
                    return -1;  
                } else if (s1 != null && s2 == null) {  
                    return 1;  
                } else {  
                    return collator_Chinese.compare(s1, s2);  
                }  
            }  
        }  
    }  
      
    public static class FullNameComparator implements Comparator<Contact> {  
        public int compare(Contact c1, Contact c2) {  
            if (c1 == null && c2 == null) {  
                return 0;  
            } else if (c1 == null && c2 != null) {  
                return -1;  
            } else if (c1 != null && c2 == null) {  
                return 1;  
            } else {  
                String s1 = c1.getFullName();  
                String s2 = c2.getFullName();  
                  
                if (s1 == null && s2 == null) {  
                    return 0;  
                } else if (s1 == null && s2 != null) {  
                    return -1;  
                } else if (s1 != null && s2 == null) {  
                    return 1;  
                } else {  
                    return collator_Chinese.compare(s1, s2);  
                }  
            }  
        }  
    }  
      
    public static class IdCardNoComparator implements Comparator<Contact> {  
        public int compare(Contact c1, Contact c2) {  
            if (c1 == null && c2 == null) {  
                return 0;  
            } else if (c1 == null && c2 != null) {  
                return -1;  
            } else if (c1 != null && c2 == null) {  
                return 1;  
            } else {  
                String s1 = c1.getIdCardNo();  
                String s2 = c2.getIdCardNo();  
                  
                if (s1 == null && s2 == null) {  
                    return 0;  
                } else if (s1 == null && s2 != null) {  
                    return -1;  
                } else if (s1 != null && s2 == null) {  
                    return 1;  
                } else {  
                    return s1.compareToIgnoreCase(s2);  
                }  
            }  
        }  
    }  
      
    public static class NationalityComparator implements Comparator<Contact> {  
        public int compare(Contact c1, Contact c2) {  
            if (c1 == null && c2 == null) {  
                return 0;  
            } else if (c1 == null && c2 != null) {  
                return -1;  
            } else if (c1 != null && c2 == null) {  
                return 1;  
            } else {  
                String s1 = c1.getNationality();  
                String s2 = c2.getNationality();  
                  
                if (s1 == null && s2 == null) {  
                    return 0;  
                } else if (s1 == null && s2 != null) {  
                    return -1;  
                } else if (s1 != null && s2 == null) {  
                    return 1;  
                } else {  
                    return collator_Chinese.compare(s1, s2);  
                }  
            }  
        }  
    }  
      
      
}  
 



然后再来看JqGridBaseAction,其中添加了一个抽象方法,用来将数据结果进行排序。

package cn.gengv.struts2ex.jqGrid;  
   
// import ...   
   
@SuppressWarnings("serial")  
public abstract class JqGridBaseAction<T> extends ActionSupport {  
    ...  
      
    // (1)添加排序方法   
    public abstract void sortResults(List<T> results, String field, String order);  
      
    public String refreshGridModel() {  
        try {  
            List<Criterion> criteria = Collections.emptyList();  
               
            if(search == true) {  
                criteria = new ArrayList<Criterion>();  
                  
                if(filters != null && filters.length()>0) {  
                    criteria.addAll(this.generateSearchCriteriaFromFilters(filters));  
                }  
                   
                Criterion criterion = this.generateSearchCriterion(searchField, searchString, searchOper);  
                if(criterion != null) {  
                    criteria.add(criterion);  
                }  
            }  
               
            List<T> results = Collections.emptyList();  
              
              
            int from = rows * (page - 1);  
            int length = 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);  
            return SUCCESS;  
        } catch (Exception e) {  
            e.printStackTrace();  
            this.addActionError(e.getMessage());  
            return ERROR;  
        }  
    }  
      
    ...  
}  


而在ListContactsAction中提供了方法实现:


package cn.gengv.struts2ex.jqGrid;  
   
import java.util.Collections;  
import java.util.Comparator;  
import java.util.List;  
import com.byzl.hare.dao.impl.Criterion;  
import com.byzl.hare.model.Contact;  
import com.byzl.hare.service.ContactService;  
   
@SuppressWarnings("serial")  
public class ListContactsAction extends JqGridBaseAction<Contact> {  
      
    ...  
      
    @Override  
    public void sortResults(List<Contact> results, String field, String order) {  
        // (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);  
            }  
        }  
          
    }  
   
    ...  
}  
 




不过这个例子存在一定的局限性,即只能将当前页中的数据根据某列进行排序;而不能跨页间进行数据排序。之所以存在这种局限,也是源于实际应用中的客观限制。还以这个例子来说,数据库里总共模拟了两万多条数据记录。如果每次要将这些记录进行排里的话,除非有数据库索引支持,否则所要消耗的时间也是相当客观的,对于用户体验来说,几乎就是灾难。如果数据量更多的话,结果可想而知。

因此,我们应该换一个角度来看这个问题,用户之所以使用排序,更多的目的还是在于查找数据方便,既然我们可以提供条件查询(尤其是复杂条件查询),那么用户对于排序的需求也就不会那么迫切了。同时也可以体会到,排序更多地应用在少量数据的场合下。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值