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

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

    博客分类: 
  • 报表 图
应用服务器 DAO Blog

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

jqGrid通过colModel选项中的sortable来控制是否可以以某列的值排序。sortable的默认值是true,当设为false时,即此列不能用于排序。

view plaincopy to clipboardprint?
01.$(function(){   
02.    $("#gridTable").jqGrid({   
03.       
04.        ...   
05.            
06.        colModel: [   
07.              {name:"id",index:"id",label:"编码",width:40},     
08.              {name:"lastName",index:"lastName",label:"姓",width:80},   
09.              {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.});  
$(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的代码:

view plaincopy to clipboardprint?
01.package cn.gengv.struts2ex.jqGrid;   
02.import java.text.Collator;   
03.import java.util.Comparator;   
04.import com.byzl.hare.model.Contact;   
05.public class ContactComparatorFactory {   
06.    private static Collator collator_Chinese = Collator.getInstance(java.util.Locale.CHINA);   
07.    private final static Comparator<Contact> idComparator = new IdComparator();   
08.    private final static Comparator<Contact> firstNameComparator = new FirstNameComparator();   
09.    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.       
175.}  
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,其中添加了一个抽象方法,用来将数据结果进行排序。

view plaincopy to clipboardprint?
01.package cn.gengv.struts2ex.jqGrid;   
02.    
03.// import ...   
04.    
05.@SuppressWarnings("serial")   
06.public abstract class JqGridBaseAction<T> extends ActionSupport {   
07.    ...   
08.       
09.    // (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.    ...   
66.}  
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中提供了方法实现:

view plaincopy to clipboardprint?
01.package cn.gengv.struts2ex.jqGrid;   
02.    
03.import java.util.Collections;   
04.import java.util.Comparator;   
05.import java.util.List;   
06.import com.byzl.hare.dao.impl.Criterion;   
07.import com.byzl.hare.model.Contact;   
08.import com.byzl.hare.service.ContactService;   
09.    
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.    ...   
33.}  
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);
            }
        }
        
    }
 
    ...





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

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

你可能感兴趣的:(c,exception,String,struts,null,Class)