我們知道,salesforce中系統標准列表頁面提供了相應的分頁功能,如果要使用其分頁功能,可以訪問http://www.cnblogs.com/zero-zyq/p/5343287.html查看相關實現。
現在很多的sfdc項目都是重構頁面進行開發,所以很多系統分裝的功能用不上,但是很多確實很常見的功能,比如分頁,這時候就有必要自己封裝一套翻頁基類,子類繼承父類並實現相關方法以后,前台通過封裝的翻頁類實現翻頁功能。
根據系統的分頁功能可以想象到我們設計的分頁類應該滿足以下簡單的功能:
1.相關sObject的數據列表,用於顯示數據;
2.首頁,尾頁;
3.上一頁,下一頁;
4.總頁數,當前頁數;
5.是否還有上一頁,下一頁;
6.每頁顯示條數(可動態顯示)。
MyPagination類封裝如下:
1 public virtual without sharing class MyPagination { 2 //默認值,如果不設置每頁顯示的數量,則默認數量為20 3 public static final Integer DEFAULT_PAGE_SIZE=20; 4 5 public MyPagination() { 6 7 } 8 9 public MyPagination(ApexPages.StandardController controller) { 10 11 } 12 13 public MyPagination(ApexPages.StandardSetController controller) { 14 15 } 16 17 //結果集 18 private List<sObject> sObjectList; 19 20 //查詢條數的SQL 21 private String countStr; 22 23 //查詢結果集的SQL 24 private String queryStr; 25 26 //查詢結果集的條件 where 部分 27 private String queryCondition; 28 29 //查詢結果集的group by部分 30 private String groupBy; 31 32 //查詢結果集的order by 部分 33 private String orderBy; 34 35 //查詢結果集的offset部分,offset最大值為2000,salesforce的限制 36 private Integer offset=0; 37 38 public List<sObject> resultList{ 39 get { 40 if(sObjectList == null){ 41 return new List<sObject>(); 42 } 43 return sObjectList; 44 } 45 set; 46 } 47 48 public virtual void setQueryCondition(String countStr,String queryStr){ 49 setQueryCondition(countStr,queryStr,null,null,null); 50 } 51 52 public virtual void setQueryCondition(String countStr,String queryStr,String queryCondition){ 53 setQueryCondition(countStr,queryStr,queryCondition,null,null); 54 } 55 56 public virtual void setQueryCondition(String countStr,String queryStr,String queryCondition,String groupBy,String orderBy){ 57 this.countStr=countStr; 58 this.queryStr=queryStr; 59 this.queryCondition=queryCondition; 60 this.groupBy=groupBy; 61 this.orderBy=orderBy; 62 buildQuery(); 63 } 64 65 private void buildQuery(){ 66 List<String> queryArgs = new List<String>(); 67 List<String> countArgs= new List<String>(); 68 if(String.isNotBlank(countStr)){ 69 countArgs.add(countStr); 70 } 71 if(String.isNotBlank(queryStr)){ 72 queryArgs.add(queryStr); 73 } 74 if(String.isNotBlank(queryCondition)){ 75 queryArgs.add(queryCondition); 76 countArgs.add(queryCondition); 77 } 78 if(String.isNotBlank(groupBy)){ 79 queryArgs.add(groupBy); 80 countArgs.add(groupBy); 81 } 82 if(String.isNotBlank(orderBy)){ 83 queryArgs.add(orderBy); 84 } 85 initTotalNum(countArgs); 86 queryStr=String.join(queryArgs,' '); 87 offset=0; 88 } 89 90 private void initTotalNum(List<String> countArgs){ 91 String countqueryStr=String.join(countArgs,' '); 92 if(String.isNotBlank(countqueryStr)){ 93 94 totalNumber=Database.countquery(countqueryStr); 95 } else { 96 totalNumber=0; 97 } 98 if(totalNumber != null) { 99 pageNumber=1; 100 } 101 } 102 103 public virtual List<sObject> getQueryResult(){ 104 if(String.isBlank(queryStr)){ 105 sObjectList = new List<sObject>(); 106 }else{ 107 String querySql=queryStr+' limit '+pageSize+' offset '+offset; 108 sObjectList = Database.query(querySql); 109 } 110 return sObjectList; 111 } 112 113 public virtual Integer getCountResult(){ 114 return totalNumber; 115 } 116 117 //改變每頁顯示的數量 118 public virtual void changePageSize(Integer pageSize) { 119 if (pageSize!=null){ 120 this.pageSize=pageSize; 121 } 122 } 123 124 //是否有下一頁 125 public Boolean hasNext { 126 get { 127 return pageSize*pageNumber<totalNumber; 128 } 129 set; 130 } 131 132 //是否有前一頁 133 public Boolean hasPrevious { 134 get { 135 return pageSize*(pageNumber-1)>0; 136 } 137 set; 138 } 139 140 public Integer pageNumber { 141 get { 142 if(pageNumber==null){ 143 pageNumber=0; 144 } 145 return pageNumber; 146 } 147 set; 148 } 149 150 //每頁顯示頁數 151 public Integer pageSize{ 152 get{ 153 if(pageSize==null){ 154 pageSize=DEFAULT_PAGE_SIZE; 155 } 156 return pageSize; 157 } 158 set; 159 } 160 161 162 //結果集總數 163 public Integer totalNumber{ 164 get{ 165 if(totalNumber==null){ 166 totalNumber=0; 167 } 168 return totalNumber; 169 } 170 set; 171 } 172 173 174 //總頁數 175 public Integer totalPage{ 176 get{ 177 if(totalNumber==0 || math.mod(totalNumber,pageSize)!=0){ 178 return totalNumber/pageSize+1; 179 }else{ 180 return totalNumber/pageSize; 181 } 182 } 183 set; 184 } 185 186 //是否有記錄集 187 public Boolean hasRecord{ 188 get { 189 if(totalNumber!=0){ 190 return true; 191 }else{ 192 return false; 193 } 194 } 195 set; 196 } 197 198 //首頁 199 public virtual void first() { 200 offset=0; 201 pageNumber=1; 202 } 203 204 //尾頁 205 public virtual void last() { 206 offset=(totalPage-1)*pageSize; 207 pageNumber=totalPage; 208 } 209 210 211 //上一頁 212 public virtual void previous() { 213 pageNumber--; 214 if(pageNumber<0){ 215 pageNumber=0; 216 offset=0; 217 }else{ 218 offset=(pageNumber-1)*pageSize; 219 } 220 } 221 222 //下一頁 223 public virtual void next() { 224 pageNumber++; 225 if(pageNumber>totalPage){ 226 pageNumber=totalPage; 227 } 228 offset=(pageNumber-1)*pageSize; 229 } 230 231 //指定頁 232 public virtual void specifiedPage(Integer pageNumber) { 233 this.pageNumber = pageNumber; 234 if(pageNumber < 0) { 235 pageNumber = 0; 236 offset = 0; 237 } else { 238 offset = (pageNumber - 1) * pageSize; 239 } 240 } 241 242 //獲取偏移量 243 public virtual Integer getOffset(){ 244 return offset; 245 } 246 247 //獲取每頁顯示條數 248 public virtual Integer getSize(){ 249 return pageSize; 250 } 251 252 253 }
MyPaginationEnhance類:

1 public without sharing class MyPaginationEnhancement{ 2 3 public static final Integer DEFAULT_PAGE_SIZE=20; 4 5 public MyPaginationEnhancement() { 6 } 7 8 public MyPaginationEnhancement(ApexPages.StandardSetController controller) { 9 } 10 11 public MyPaginationEnhancement(ApexPages.StandardController controller) { 12 } 13 14 private List<sObject> sObjectList; 15 16 private String countStr; 17 18 private String queryStr; 19 20 private String queryCondition; 21 22 private String groupBy; 23 24 private String orderBy; 25 26 private Integer offset=0; 27 28 public List<sObject> resultList{ 29 get { 30 if(sObjectList == null){ 31 return new List<sObject>(); 32 } 33 return sObjectList; 34 } 35 set; 36 } 37 38 public List<sObject> getQueryResult(String countStr,String queryStr,String queryCondition){ 39 setQueryCondition(countStr,queryStr,queryCondition,null,null); 40 buildAndQuery(); 41 return sObjectList; 42 } 43 44 public List<sObject> getQueryResult(String countStr,String queryStr,String queryCondition,String groupBy,String orderBy){ 45 setQueryCondition(countStr,queryStr,queryCondition,groupBy,orderBy); 46 buildAndQuery(); 47 return sObjectList; 48 } 49 50 public List<sObject> updateQueryResult(String queryStr,String queryCondition,String groupBy,String orderBy){ 51 String querySql = queryStr; 52 if(queryCondition!=null){ 53 querySql += queryCondition; 54 } 55 if(groupBy!=null){ 56 querySql +=groupBy; 57 } 58 if(orderBy!=null){ 59 querySql +=orderBy; 60 } 61 sObjectList = Database.query(querySql); 62 return sObjectList; 63 } 64 65 private void setQueryCondition(String countStr,String queryStr,String queryCondition,String groupBy,String orderBy){ 66 this.countStr=countStr; 67 this.queryStr=queryStr; 68 this.queryCondition=queryCondition; 69 this.groupBy=groupBy; 70 this.orderBy=orderBy; 71 } 72 73 private void buildAndQuery(){ 74 List<String> queryArgs = new List<String>(); 75 List<String> countArgs= new List<String>(); 76 if(String.isNotBlank(countStr)){ 77 countArgs.add(countStr); 78 } 79 if(String.isNotBlank(queryStr)){ 80 queryArgs.add(queryStr); 81 } 82 if(String.isNotBlank(queryCondition)){ 83 queryArgs.add(queryCondition); 84 countArgs.add(queryCondition); 85 } 86 if(String.isNotBlank(groupBy)){ 87 queryArgs.add(groupBy); 88 countArgs.add(groupBy); 89 } 90 if(String.isNotBlank(orderBy)){ 91 queryArgs.add(orderBy); 92 } 93 initTotalNum(countArgs); 94 queryResult(queryArgs); 95 } 96 97 private void initTotalNum(List<String> countArgs){ 98 String countqueryStr=String.join(countArgs,' '); 99 100 if(String.isNotBlank(countqueryStr)){ 101 102 totalNumber=Database.countquery(countqueryStr); 103 } else { 104 totalNumber=0; 105 } 106 107 if(totalNumber !=0 && pageNumber==0){ 108 pageNumber = 1; 109 } 110 } 111 112 private List<sObject> queryResult(List<String> queryArgs){ 113 queryStr=String.join(queryArgs,' '); 114 if(String.isBlank(queryStr)){ 115 sObjectList = new List<sObject>(); 116 }else{ 117 String querySql=queryStr+' limit '+pageSize+' offset '+offset; 118 119 sObjectList = Database.query(querySql); 120 } 121 return sObjectList; 122 } 123 124 public void changePageSize(Integer pageSize) { 125 if (pageSize!=null){ 126 this.pageSize=pageSize; 127 } 128 } 129 130 public Boolean hasNext { 131 get { 132 return pageSize*pageNumber<totalNumber; 133 } 134 set; 135 } 136 137 public Boolean hasPrevious { 138 get { 139 return pageSize*(pageNumber-1)>0; 140 } 141 set; 142 } 143 144 public Integer pageNumber { 145 get { 146 if(pageNumber==null){ 147 pageNumber=0; 148 } 149 return pageNumber; 150 } 151 set; 152 } 153 154 public Integer pageSize{ 155 get{ 156 if(pageSize==null){ 157 pageSize=DEFAULT_PAGE_SIZE; 158 } 159 return pageSize; 160 } 161 set; 162 } 163 164 public Integer totalNumber{ 165 get{ 166 if(totalNumber==null){ 167 totalNumber=0; 168 } 169 return totalNumber; 170 } 171 set; 172 } 173 174 public Integer totalPage{ 175 get{ 176 if(totalNumber==0 || math.mod(totalNumber,pageSize)!=0){ 177 return totalNumber/pageSize+1; 178 }else{ 179 return totalNumber/pageSize; 180 } 181 } 182 set; 183 } 184 185 public Boolean hasRecord{ 186 get { 187 if(totalNumber!=0){ 188 return true; 189 }else{ 190 return false; 191 } 192 } 193 set; 194 } 195 196 public void first() { 197 offset=0; 198 pageNumber=1; 199 } 200 201 public void last() { 202 offset=(totalPage-1)*pageSize; 203 pageNumber=totalPage; 204 } 205 206 public void previous() { 207 pageNumber--; 208 if(pageNumber<0){ 209 pageNumber=0; 210 offset=0; 211 }else{ 212 offset=(pageNumber-1)*pageSize; 213 } 214 } 215 216 public void next() { 217 pageNumber++; 218 if(pageNumber>totalPage){ 219 pageNumber=totalPage; 220 } 221 offset=(pageNumber-1)*pageSize; 222 } 223 224 //指定頁 225 public virtual void specifiedPage(Integer pageNumber) { 226 this.pageNumber = pageNumber; 227 if(pageNumber < 0) { 228 pageNumber = 0; 229 offset = 0; 230 } else { 231 offset = (pageNumber - 1) * pageSize; 232 } 233 } 234 235 public Integer getOffset(){ 236 return offset; 237 } 238 239 public Integer getSize(){ 240 return pageSize; 241 } 242 243 }
部分變量解釋:
1.sObjectList:封裝SOQL查詢出來的sObject的結果集;
2.countStr:SOQL查詢條數的SQL語句;
3.queryStr:SOQL查詢結果集的SQL語句;
4.queryCondition:SOQL中查詢結果集條件部分語句(where xxx);
5.groupBy:如果SOQL需要用到分組或者聚合函數等,則設置此變量group by語句;
6.orderBy:如果SOQL需要按照某個或者某些字段進行升序或者降序排列,則設置此變量order by語句;
7.offset:偏移量,SOQL中對於偏移量最大設置的值為2000,超過2000則拋出異常;
8.hasNext:數據當前頁是否還有下一頁;
9.hasPrevious :數據當前頁是否還有上一頁;
10.pageNumber:當前頁數;
11.pageSize:每頁顯示條數;
12.totalNumber:結果集總數;
13.totalPage:總頁數;
14.hasRecord:結果集是否為空。
部分方法解釋:
1.setQueryCondition:設置查詢條件,通過子類的SQL查詢條件拼裝成需要執行的SQL,此方法有三種重構函數,涵蓋了主要的SQL查詢條件的用法,如果有其他需求,可以繼續重構;
2.initTotalNum:獲取結果集總數;
3.buildQuery:通過基礎SQL以及query condition將其拼裝成一個完整的SQL語句;
4.getQueryResult:通過拼裝成完整的SQL語句進行查詢,返回查詢出來的結果列表;
5.changePageSize:改變每頁顯示的數據條數;
6.first:跳轉到首頁;
7.last:跳轉到尾頁;
8.previous:跳轉到上一頁;
9.next:跳轉到下一頁;
10.specifiedPage:跳轉到指定頁數。
總結:對於一般的分頁功能,此基類基本封裝,故項目要求沒有特別高情況下可以直接使用此基類,有的人會說offset最大限制是2000,如果超過2000基類中沒有處理會不會不好。這個覺得因設計而異,controller層使用pagination后,執行sql查詢列表前應先查一下offset是否已經超過了2000,如果超過2000可以給前台拋出自定義友好的異常或者設置offset為2000,這樣做法會比在基類中強制寫死比較好。篇中如果有錯誤地方歡迎指正,如果有不懂地方歡迎留言。