在线电子商务网站 分页 的封装

首先创建一个QueryResult类来存放结果集和总记录数:package cn.wuxing.bean;

View Code
 1 import java.util.List;
2
3 public class QueryResult<T> {
4 private List<T> resultlist;
5 private long totalrecord;
6
7 public List<T> getResultlist() {
8 return resultlist;
9 }
10 public void setResultlist(List<T> resultlist) {
11 this.resultlist = resultlist;
12 }
13 public long getTotalrecord() {
14 return totalrecord;
15 }
16 public void setTotalrecord(long totalrecord) {
17 this.totalrecord = totalrecord;
18 }
19 }

接下来在DaoSupport类里面添加如下方法:

View Code
 1 /**
2 * 分页获取记录
3 * @param firstindex 开始索引,如果输入值为-1,即获取全部数据
4 * @param maxresult 每页获取的记录数,如果输入值为-1,即获取全部数据
5 * @param wherejpql 条件语句,不带where关键字,条件语句只能使用位置参数,位置参数索引以1开始,如:o.username=?1 and o.password=?2
6 * @param params 条件语句出现的位置参数
7 * @param orderby 排序,Key为排序属性,Value为asc/desc
8 */
9 @Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED)
10 public QueryResult<T> getScrollData(int firstindex, int maxresult
11 , String wherejpql, Object[] queryParams,LinkedHashMap<String, String> orderby) {
12 QueryResult qr = new QueryResult<T>();
13 String entityname = getEntityName(this.entityClass);
14 Query query = em.createQuery("select o from "+ entityname+ " o "+(wherejpql==null || "".equals(wherejpql.trim())? "": "where "+ wherejpql)+ buildOrderby(orderby));
15 setQueryParams(query, queryParams);
16 if(firstindex!=-1 && maxresult!=-1) query.setFirstResult(firstindex).setMaxResults(maxresult);
17 qr.setResultlist(query.getResultList());
18 query = em.createQuery("select count("+ getCountField(this.entityClass)+ ") from "+ entityname+ " o "+(wherejpql==null || "".equals(wherejpql.trim())? "": "where "+ wherejpql));
19 setQueryParams(query, queryParams);
20 qr.setTotalrecord((Long)query.getSingleResult());
21 return qr;
22 }
23
24 protected static void setQueryParams(Query query, Object[] queryParams){
25 if(queryParams!=null && queryParams.length>0){
26 for(int i=0; i<queryParams.length; i++){
27 query.setParameter(i+1, queryParams[i]);
28 }
29 }
30 }
31 /**
32 * 组装order by语句
33 * @param orderby
34 * @return
35 */
36 protected static String buildOrderby(LinkedHashMap<String, String> orderby){
37 StringBuffer orderbyql = new StringBuffer("");
38 if(orderby!=null && orderby.size()>0){
39 orderbyql.append(" order by ");
40 for(String key : orderby.keySet()){
41 orderbyql.append("o.").append(key).append(" ").append(orderby.get(key)).append(",");
42 }
43 orderbyql.deleteCharAt(orderbyql.length()-1);
44 }
45 return orderbyql.toString();
46 }
47 /**
48 * 获取实体的名称
49 * @param <E>
50 * @param clazz 实体类
51 * @return
52 */
53 protected static <E> String getEntityName(Class<E> clazz){
54 String entityname = clazz.getSimpleName();
55 Entity entity = clazz.getAnnotation(Entity.class);
56 if(entity.name()!=null && !"".equals(entity.name())){
57 entityname = entity.name();
58 }
59 return entityname;
60 }
61
62 protected static <E> String getCountField(Class<E> clazz){
63 String out = "o";
64 try {
65 PropertyDescriptor[] propertyDescriptors = Introspector.getBeanInfo(clazz).getPropertyDescriptors();
66 for(PropertyDescriptor propertydesc : propertyDescriptors){
67 Method method = propertydesc.getReadMethod();
68 if(method!=null && method.isAnnotationPresent(EmbeddedId.class)){
69 PropertyDescriptor[] ps = Introspector.getBeanInfo(propertydesc.getPropertyType()).getPropertyDescriptors();
70 out = "o."+ propertydesc.getName()+ "." + (!ps[1].getName().equals("class")? ps[1].getName(): ps[0].getName());
71 break;
72 }
73 }
74 } catch (Exception e) {
75 e.printStackTrace();
76 }
77 return out;
78 }

 

 getScrollData是最主要的方法,可以对分页进行排序、加条件等等。

 

  我们可以讲getScrollData得到的值存放到下面这个类中,请注意这个类的注释以及相关方法的注释:

 

 

View Code
 1 import java.util.List;
2
3 /**
4 * 封装了Action向jsf所存放的一些数据
5 * 该类最重要的是调用setQueryResult方法,他会连环设置该类其他属性的值。
6 * @author bruce
7 * @param <T>
8 */
9 public class PageView<T> {
10 /** 分页数据 **/
11 private List<T> records;
12 /** 页码开始索引和结束索引 **/
13 private PageIndex pageindex;
14 /** 总页数 **/
15 private long totalpage = 1;
16 /** 每页显示记录数 **/
17 private int maxresult = 12;
18 /** 当前页 **/
19 private int currentpage = 1;
20 /** 总记录数 **/
21 private long totalrecord;
22 /** 页码数量 **/
23 private int pagecode = 10;
24 /** 要获取记录的开始索引 **/
25 public int getFirstResult() {
26 return (this.currentpage-1)*this.maxresult;
27 }
28 public int getPagecode() {
29 return pagecode;
30 }
31
32 public void setPagecode(int pagecode) {
33 this.pagecode = pagecode;
34 }
35
36 /**
37 * 构造方法,要使用这个类,必须传进每页显示记录数和当前页。
38 * @param maxresult
39 * @param currentpage
40 */
41 public PageView(int maxresult, int currentpage) {
42 this.maxresult = maxresult;
43 this.currentpage = currentpage;
44 }
45
46 /**
47 * 该方法存在一个连环的调用
48 * 将从数据库分页查询出来的总结果集和总记录数设置进来。
49 * 在设置总记录数的同时,会换算出总页数。详情参看setTotalrecord方法。
50 * 在设置总页数的同时,包含分页的开始索引和结束索引的PageIndex对象也确定了下来。详情参看setTotalpage方法。
51 * @param qr
52 */
53 public void setQueryResult(QueryResult<T> qr){
54 setRecords(qr.getResultlist());
55 setTotalrecord(qr.getTotalrecord());
56 }
57
58 public long getTotalrecord() {
59 return totalrecord;
60 }
61 /**
62 * 在设置总记录数的同时,会将总页数也设置进来。
63 * 在设置总页数的同时,包含分页的开始索引和结束索引的PageIndex对象也确定了下来。
64 * @param totalrecord
65 */
66 public void setTotalrecord(long totalrecord) {
67 this.totalrecord = totalrecord;
68 setTotalpage(this.totalrecord%this.maxresult==0? this.totalrecord/this.maxresult : this.totalrecord/this.maxresult+1);
69 }
70 public List<T> getRecords() {
71 return records;
72 }
73 public void setRecords(List<T> records) {
74 this.records = records;
75 }
76 public PageIndex getPageindex() {
77 return pageindex;
78 }
79 public long getTotalpage() {
80 return totalpage;
81 }
82 public void setTotalpage(long totalpage) {
83 this.totalpage = totalpage;
84 this.pageindex = PageIndex.getPageIndex(pagecode, currentpage, totalpage);
85 }
86 public int getMaxresult() {
87 return maxresult;
88 }
89 public int getCurrentpage() {
90 return currentpage;
91 }
92 }

PageView用到了一个类PageIndex:

View Code
 1 /**
2 * 此类有一个静态方法,返回带有分页的开始索引和结束索引值的对象
3 */
4 public class PageIndex {
5 private long startindex;
6 private long endindex;
7
8 public PageIndex(long startindex, long endindex) {
9 this.startindex = startindex;
10 this.endindex = endindex;
11 }
12 public long getStartindex() {
13 return startindex;
14 }
15 public void setStartindex(long startindex) {
16 this.startindex = startindex;
17 }
18 public long getEndindex() {
19 return endindex;
20 }
21 public void setEndindex(long endindex) {
22 this.endindex = endindex;
23 }
24
25 /**
26 * 静态方法来获取分页的开始索引和结束索引的值
27 * @param viewpagecount 分页栏总共显示多少个页码
28 * @param currentPage 当前页码值
29 * @param totalpage 总共页码值
30 * @return 带有开始索引和结束索引的页码对象
31 */
32 public static PageIndex getPageIndex(long viewpagecount, int currentPage, long totalpage){
33 long startpage = currentPage-(viewpagecount%2==0? viewpagecount/2-1 : viewpagecount/2);
34 long endpage = currentPage+viewpagecount/2;
35 if(startpage<1){
36 startpage = 1;
37 if(totalpage>=viewpagecount) endpage = viewpagecount;
38 else endpage = totalpage;
39 }
40 if(endpage>totalpage){
41 endpage = totalpage;
42 if((endpage-viewpagecount)>0) startpage = endpage-viewpagecount+1;
43 else startpage = 1;
44 }
45 return new PageIndex(startpage, endpage);
46 }
47 }

前台jsp的封装如下:

View Code
1 <%@ page language="java" pageEncoding="UTF-8"%>
2 <font color="#FFFFFF">
3 当前页:第${pageView.currentpage}页 | 总记录数:${pageView.totalrecord}条 | 每页显示:${pageView.maxresult}条 | 总页数:${pageView.totalpage}页</font> 
4 <c:forEach begin="${pageView.pageindex.startindex}" end="${pageView.pageindex.endindex}" var="wp">
5 <c:if test="${pageView.currentpage==wp}"><b><font color="#FFFFFF">第${wp}页</font></b></c:if>
6 <c:if test="${pageView.currentpage!=wp}"><a href="javascript:topage('${wp}')" class="a03">第${wp}页</a></c:if>
7 </c:forEach>

倒数第二行用到了a href="javascript:topage('${wp}')"而不是直接写链接地址,这是因为这个jsp是封装好的,以后别的jsp调用就可以直接写一个topage的js方法来将链接地址写入。

 

posted @ 2012-04-07 21:44  jerry_xing8  阅读(1593)  评论(0编辑  收藏  举报