您的位置:首页 > 编程语言 > Java开发

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

2011-08-23 15:32 351 查看


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

博客分类:

报表 图

应用服务器DAOBlog

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

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);

}

}

}

...

}

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

因此,我们应该换一个角度来看这个问题,用户之所以使用排序,更多的目的还是在于查找数据方便,既然我们可以提供条件查询(尤其是复杂条件查询),那么用户对于排序的需求也就不会那么迫切了。同时也可以体会到,排序更多地应用在少量数据的场合下
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: