我们知道,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,这样做法会比在基类中强制写死比较好。篇中如果有错误地方欢迎指正,如果有不懂地方欢迎留言。