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

终于讲到排序了,这一部分应该说还是比较好理解的。
jqGrid通过colModel选项中的sortable来控制是否可以以某列的值排序。sortable的默认值是true,当设为false时,即此列不能用于排序。

[javascript] view plain copy
  1. $(function(){ 
  2.     $("#gridTable").jqGrid({ 
  3.      
  4.         ... 
  5.           
  6.         colModel: [ 
  7.               {name:"id",index:"id",label:"编码",width:40},   
  8.               {name:"lastName",index:"lastName",label:"姓",width:80}, 
  9.               {name:"firstName",index:"firstName",label:"名",width:80}, 
  10.               {name:"email",index:"email",label:"电子邮箱",width:160,sortable:false}, 
  11.               {name:"telNo",index:"telNo",label:"电话",width:120,sortable:false
  12.         ], 
  13.          
  14.         ... 
  15.          
  16.     }); 
  17. }); 


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

  1. package cn.gengv.struts2ex.jqGrid; 
  2. import java.text.Collator; 
  3. import java.util.Comparator; 
  4. import com.byzl.hare.model.Contact; 
  5. public class ContactComparatorFactory { 
  6.     private static Collator collator_Chinese = Collator.getInstance(java.util.Locale.CHINA); 
  7.     private final static Comparator<Contact> idComparator = new IdComparator(); 
  8.     private final static Comparator<Contact> firstNameComparator = new FirstNameComparator(); 
  9.     private final static Comparator<Contact> lastNameComparator = new LastNameComparator(); 
  10.     private final static Comparator<Contact> fullNameComparator = new FullNameComparator(); 
  11.     private final static Comparator<Contact> idCardNoNoComparator = new IdCardNoComparator(); 
  12.     private final static Comparator<Contact> nationalityComparator = new NationalityComparator(); 
  13.      
  14.      
  15.     public static Comparator<Contact> getComparator(String compareType) { 
  16.         if ("id".equalsIgnoreCase(compareType)) { 
  17.             return idComparator; 
  18.         } else if ("firstName".equalsIgnoreCase(compareType)) { 
  19.             return firstNameComparator; 
  20.         } else if ("lastName".equalsIgnoreCase(compareType)) { 
  21.             return lastNameComparator; 
  22.         } else if ("fullName".equalsIgnoreCase(compareType)) { 
  23.             return fullNameComparator; 
  24.         } else if ("idCardNoNo".equalsIgnoreCase(compareType)) { 
  25.             return idCardNoNoComparator; 
  26.         } else if ("nationality".equalsIgnoreCase(compareType)) { 
  27.             return nationalityComparator; 
  28.         } else
  29.             return null
  30.         } 
  31.     } 
  32.      
  33.     public static class IdComparator implements Comparator<Contact> { 
  34.         public int compare(Contact c1, Contact c2) { 
  35.             if (c1 == null && c2 == null) { 
  36.                 return 0
  37.             } else if (c1 == null && c2 != null) { 
  38.                 return -1
  39.             } else if (c1 != null && c2 == null) { 
  40.                 return 1
  41.             } else
  42.                 int id1 = c1.getId(); 
  43.                 int id2 = c2.getId(); 
  44.                 return id1 == id2 ? 0 : (id1 < id2 ? -1 : 1); 
  45.             } 
  46.         } 
  47.     } 
  48.      
  49.     public static class FirstNameComparator implements Comparator<Contact> { 
  50.         public int compare(Contact c1, Contact c2) { 
  51.             if (c1 == null && c2 == null) { 
  52.                 return 0
  53.             } else if (c1 == null && c2 != null) { 
  54.                 return -1
  55.             } else if (c1 != null && c2 == null) { 
  56.                 return 1
  57.             } else
  58.                 String s1 = c1.getFirstName(); 
  59.                 String s2 = c2.getFirstName(); 
  60.                  
  61.                 if (s1 == null && s2 == null) { 
  62.                     return 0
  63.                 } else if (s1 == null && s2 != null) { 
  64.                     return -1
  65.                 } else if (s1 != null && s2 == null) { 
  66.                     return 1
  67.                 } else
  68.                     return collator_Chinese.compare(s1, s2); 
  69.                 } 
  70.             } 
  71.         } 
  72.     } 
  73.      
  74.     public static class LastNameComparator implements Comparator<Contact> { 
  75.         public int compare(Contact c1, Contact c2) { 
  76.             if (c1 == null && c2 == null) { 
  77.                 return 0
  78.             } else if (c1 == null && c2 != null) { 
  79.                 return -1
  80.             } else if (c1 != null && c2 == null) { 
  81.                 return 1
  82.             } else
  83.                 String s1 = c1.getLastName(); 
  84.                 String s2 = c2.getLastName(); 
  85.                  
  86.                 if (s1 == null && s2 == null) { 
  87.                     return 0
  88.                 } else if (s1 == null && s2 != null) { 
  89.                     return -1
  90.                 } else if (s1 != null && s2 == null) { 
  91.                     return 1
  92.                 } else
  93.                     return collator_Chinese.compare(s1, s2); 
  94.                 } 
  95.             } 
  96.         } 
  97.     } 
  98.      
  99.     public static class FullNameComparator implements Comparator<Contact> { 
  100.         public int compare(Contact c1, Contact c2) { 
  101.             if (c1 == null && c2 == null) { 
  102.                 return 0
  103.             } else if (c1 == null && c2 != null) { 
  104.                 return -1
  105.             } else if (c1 != null && c2 == null) { 
  106.                 return 1
  107.             } else
  108.                 String s1 = c1.getFullName(); 
  109.                 String s2 = c2.getFullName(); 
  110.                  
  111.                 if (s1 == null && s2 == null) { 
  112.                     return 0
  113.                 } else if (s1 == null && s2 != null) { 
  114.                     return -1
  115.                 } else if (s1 != null && s2 == null) { 
  116.                     return 1
  117.                 } else
  118.                     return collator_Chinese.compare(s1, s2); 
  119.                 } 
  120.             } 
  121.         } 
  122.     } 
  123.      
  124.     public static class IdCardNoComparator implements Comparator<Contact> { 
  125.         public int compare(Contact c1, Contact c2) { 
  126.             if (c1 == null && c2 == null) { 
  127.                 return 0
  128.             } else if (c1 == null && c2 != null) { 
  129.                 return -1
  130.             } else if (c1 != null && c2 == null) { 
  131.                 return 1
  132.             } else
  133.                 String s1 = c1.getIdCardNo(); 
  134.                 String s2 = c2.getIdCardNo(); 
  135.                  
  136.                 if (s1 == null && s2 == null) { 
  137.                     return 0
  138.                 } else if (s1 == null && s2 != null) { 
  139.                     return -1
  140.                 } else if (s1 != null && s2 == null) { 
  141.                     return 1
  142.                 } else
  143.                     return s1.compareToIgnoreCase(s2); 
  144.                 } 
  145.             } 
  146.         } 
  147.     } 
  148.      
  149.     public static class NationalityComparator implements Comparator<Contact> { 
  150.         public int compare(Contact c1, Contact c2) { 
  151.             if (c1 == null && c2 == null) { 
  152.                 return 0
  153.             } else if (c1 == null && c2 != null) { 
  154.                 return -1
  155.             } else if (c1 != null && c2 == null) { 
  156.                 return 1
  157.             } else
  158.                 String s1 = c1.getNationality(); 
  159.                 String s2 = c2.getNationality(); 
  160.                  
  161.                 if (s1 == null && s2 == null) { 
  162.                     return 0
  163.                 } else if (s1 == null && s2 != null) { 
  164.                     return -1
  165.                 } else if (s1 != null && s2 == null) { 
  166.                     return 1
  167.                 } else
  168.                     return collator_Chinese.compare(s1, s2); 
  169.                 } 
  170.             } 
  171.         } 
  172.     } 
  173.      
  174.      


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

  1. package cn.gengv.struts2ex.jqGrid; 
  2.   
  3. // import ... 
  4.   
  5. @SuppressWarnings("serial"
  6. public abstract class JqGridBaseAction<T> extends ActionSupport { 
  7.     ... 
  8.      
  9.     // (1)添加排序方法 
  10.     public abstract void sortResults(List<T> results, String field, String order); 
  11.      
  12.     public String refreshGridModel() { 
  13.         try
  14.             List<Criterion> criteria = Collections.emptyList(); 
  15.               
  16.             if(search == true) { 
  17.                 criteria = new ArrayList<Criterion>(); 
  18.                  
  19.                 if(filters != null && filters.length()>0) { 
  20.                     criteria.addAll(this.generateSearchCriteriaFromFilters(filters)); 
  21.                 } 
  22.                   
  23.                 Criterion criterion = this.generateSearchCriterion(searchField, searchString, searchOper); 
  24.                 if(criterion != null) { 
  25.                     criteria.add(criterion); 
  26.                 } 
  27.             } 
  28.               
  29.             List<T> results = Collections.emptyList(); 
  30.              
  31.              
  32.             int from = rows * (page - 1); 
  33.             int length = rows;  
  34.              
  35.             if(loadonce) { 
  36.                 from = 0
  37.                 length = 100
  38.             } 
  39.               
  40.             if(!criteria.isEmpty()) { 
  41.                 record = this.getResultSize(criteria); 
  42.                 results = this.listResults(criteria, from, length); 
  43.                  
  44.             } else
  45.                 record = this.getResultSize(); 
  46.                 results = this.listResults(from, length); 
  47.                  
  48.             } 
  49.              
  50.             // (2)将结果排序 
  51.             if(sidx != null && sord != null) { 
  52.                 sortResults(results, sidx, sord); 
  53.             } 
  54.   
  55.             this.setGridModel(results); 
  56.             total = (int) Math.ceil((double) record / (double) rows); 
  57.             return SUCCESS; 
  58.         } catch (Exception e) { 
  59.             e.printStackTrace(); 
  60.             this.addActionError(e.getMessage()); 
  61.             return ERROR; 
  62.         } 
  63.     } 
  64.      
  65.     ... 


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

  1. package cn.gengv.struts2ex.jqGrid; 
  2.   
  3. import java.util.Collections; 
  4. import java.util.Comparator; 
  5. import java.util.List; 
  6. import com.byzl.hare.dao.impl.Criterion; 
  7. import com.byzl.hare.model.Contact; 
  8. import com.byzl.hare.service.ContactService; 
  9.   
  10. @SuppressWarnings("serial"
  11. public class ListContactsAction extends JqGridBaseAction<Contact> { 
  12.      
  13.     ... 
  14.      
  15.     @Override 
  16.     public void sortResults(List<Contact> results, String field, String order) { 
  17.         // (1)根据field获得对应的Comparator 
  18.         Comparator<Contact> comparator = ContactComparatorFactory.getComparator(field); 
  19.          
  20.         if(comparator != null) { 
  21.             // (2)使用Comparator排序 
  22.             Collections.sort(results, comparator); 
  23.              
  24.             // (3)如果需要的排序顺序为desc,则颠倒顺序 
  25.             if("desc".equals(order)) { 
  26.                 Collections.reverse(results); 
  27.             } 
  28.         } 
  29.          
  30.     } 
  31.   
  32.     ... 


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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值