內(nèi)蒙古java團(tuán)隊(duì)

          j2se,j2ee開發(fā)組
          posts - 139, comments - 212, trackbacks - 0, articles - 65
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理
          到分頁算法,一般WEB開發(fā)都會用到,我只是在我的實(shí)現(xiàn)技術(shù)上用了struts框架,其實(shí)原理都一樣的。
          看了網(wǎng)上相當(dāng)多的分頁算法,有對的也有好多是錯的,更有好多是不太優(yōu)化的。還有以前自己在augmentum做的一個(gè)分頁算法,總結(jié)了一些不足。決定重新再寫一個(gè)分頁算法。
          首先,應(yīng)該寫個(gè)bean來記錄存儲一些頁面的屬性
          分頁大致需要如下屬性:

          ?private?int?currentPage?=?1;?//?當(dāng)前頁

          ?private?int?totalPages?=?0;?//?總頁數(shù)

          ?private?int?pageRecorders?=?5;//?每頁5條數(shù)據(jù)?

          ?private?int?totalRows?=?0;?//?總數(shù)據(jù)數(shù)

          ?private?int?pageStartRow?=?0;//?每頁的起始數(shù)

          ?private?int?pageEndRow?=?0;?//?每頁顯示數(shù)據(jù)的終止數(shù)

          ?private?boolean?hasNextPage?=?false;?//?是否有下一頁

          ?private?boolean?hasPreviousPage?=?false;?//?是否有前一頁
          ?
          ?private?int?nextPage?=?0;//下一頁的頁碼
          ?
          ?private?int?previousPage?=?0;//上一頁的頁碼

          然后這些屬性之間是有聯(lián)系的,我們可以在構(gòu)造函數(shù)的時(shí)候就初始化一些屬性
          有兩種方法:
          一,根據(jù)總的頁數(shù),(假設(shè)當(dāng)前頁為1)
          ?public?PageBean(int?totalRows){
          ??this.totalRows?=?totalRows;
          ??this.currentPage?=?1;
          ??hasPreviousPage?=?false;
          ??if?((totalRows?%?pageRecorders)?==?0)?{
          ???totalPages?=?totalRows?/?pageRecorders;
          ??}?else?{
          ???totalPages?=?totalRows?/?pageRecorders?+?1;
          ??}
          ??if?(totalRows?>=?pageRecorders)?{
          ???hasNextPage?=?true;
          ???nextPage?=?2;
          ???this.pageEndRow?=?pageRecorders;
          ??}?else?{
          ???this.pageEndRow?=?totalRows;
          ???hasNextPage?=?false;
          ???nextPage?=?1;
          ??}
          ???this.pageStartRow?=?0;??
          ???previousPage?=?1;
          ?}
          然后在按下一頁或者上一頁的時(shí)候需要如下函數(shù)處理:
          public?void?nextPage()?{
          ??if(hasNextPage?==?true)
          ??currentPage?=?currentPage?+?1;
          ??if?((currentPage?-?1)?>?0)?{
          ???hasPreviousPage?=?true;
          ??}?else?{
          ???hasPreviousPage?=?false;
          ??}
          ??if?(currentPage?>=?totalPages)?{
          ???hasNextPage?=?false;
          ???this.nextPage?=?currentPage;
          ??}?else?{
          ???hasNextPage?=?true;
          ???nextPage?=?currentPage+1;
          ??}
          ??this.pageStartRow?=?(currentPage?-1)?*?pageRecorders;
          ??if(hasNextPage?==?true)
          ??this.pageEndRow?=?pageStartRow?+?5;
          ??else{
          ???this.pageEndRow?=this.totalPages;
          ??}
          ??previousPage?=?currentPage?-?1;
          ?}
          ?
          ?public?void?previousPage()?{
          ??if(hasPreviousPage?==?true)
          ??currentPage?=?currentPage?-?1;
          ??if?(currentPage?==?0)?{
          ???currentPage?=?1;
          ??}
          ??if?(currentPage?>=?totalPages)?{
          ???hasNextPage?=?false;
          ??}?else?{
          ???hasNextPage?=?true;
          ??}
          ??nextPage?=?currentPage?+?1;
          ??if?((currentPage?-?1)?>?0)?{
          ???hasPreviousPage?=?true;
          ???previousPage?=?currentPage?-?1;
          ??}?else?{
          ???hasPreviousPage?=?false;
          ???previousPage?=?currentPage;
          ??}
          ??
          ??this.pageStartRow?=?(currentPage?-1)?*?pageRecorders;
          ??if(hasNextPage?==?true)
          ??this.pageEndRow?=?pageStartRow?+?5;
          ??else{
          ???this.pageEndRow?=this.totalPages;
          ??}
          ?}
          在HTML中按下一頁或者上一頁的時(shí)候有如下代碼:
          <logic:equal?name="page"?property="hasNextPage"?value="true">
          <html:link?page="/List.do?action=nextPage">
          nextPage
          </html:link>
          </logic:equal>
          <logic:equal?name="page"?property="hasPreviousPage"?value="true">
          <html:link?page="/List.do?action=previousPage">
          PreviousPage
          </html:link>
          </logic:equal>
          然后在Action中作如下處理:??
          ??String?currentPage?=?request.getParameter("currentPage");
          ??HttpSession?session?=?request.getSession();?
          ??EmployeeForm?employeeForm?=?(EmployeeForm)?form;
          ??String?queryString?=?null;
          ??String?queryCon?=?null;
          ??String?action?=?employeeForm.getAction();
          ??List?list?=?new?ArrayList();
          ??PageBean?pb?=?null;
          ??EmployeeDao?employeeDao?=?new?EmployeeDao();
          ??if(action?==?null?||?action.equals("null")){
          ???int?totalRows?=?employeeDao.getTotalRows();
          ??
          ????pb?=?new?PageBean(totalRows);
          ????session.removeAttribute("page");
          ????queryString?=?employeeForm.getQueryString();
          ????queryCon?=?employeeForm.getQueryCon();
          ????session.setAttribute("queryString",queryString);
          ????session.setAttribute("queryCon",queryCon);???
          ????list?=?employeeDao.getAllEmployee(queryString,?queryCon,
          ??????String.valueOf(pb.getPageStartRow()),
          ??????String.valueOf(pb.getPageRecorders()));
          ???????
          ??}else?if(action.equals("nextPage")){
          ???queryString?=?(String)session.getAttribute("queryString");
          ???queryCon?=?(String)session.getAttribute("queryCon");??????
          ???employeeForm.setQueryString(queryString);
          ???employeeForm.setQueryCon(queryCon);
          ???pb?=?(PageBean)session.getAttribute("page");
          ???pb.nextPage();
          ???list?=?employeeDao.getAllEmployee(queryString,?queryCon,
          ?????String.valueOf(pb.getPageStartRow()),
          ?????String.valueOf(pb.getPageRecorders()));
          ??}else?if(action.equals("previousPage")){
          ???queryString?=?(String)session.getAttribute("queryString");
          ???queryCon?=?(String)session.getAttribute("queryCon");
          ???employeeForm.setQueryString(queryString);
          ???employeeForm.setQueryCon(queryCon);
          ???pb?=?(PageBean)session.getAttribute("page");???
          ???pb.previousPage();
          ???list?=?employeeDao.getAllEmployee(queryString,?queryCon,
          ?????String.valueOf(pb.getPageStartRow()),
          ?????String.valueOf(pb.getPageRecorders()));
          ??}
          ????????
          ????????pb.description();
          ????????session.setAttribute("page",pb);????????
          ??request.setAttribute("admin",?"admin");
          ??request.setAttribute("employee",?list);
          ??return?mapping.findForward("showlist");
          ??然后在數(shù)據(jù)庫查詢中有如下代碼:
          /**
          *查詢總記錄數(shù)
          */
          ?public?int?getTotalRows()?{
          ??int?totalRows?=?0;
          ??String?sql?=?"select?count(*)?from?employee";//假設(shè)是員工表
          ??Database?db?=?new?Database();
          ??ResultSet?rs?=?db.executeQuery(sql);
          ??try?{
          ???while?(rs.next())?{
          ????String?id?=?(String)?rs.getString(1);
          ????totalRows?=?Integer.parseInt(id);
          ???}
          ??}?catch?(SQLException?e)?{
          ???e.printStackTrace();
          ??}
          ??db.close();
          ??return?totalRows;
          ?}
          ?
          /*
          *查詢每一頁需要查詢的頁碼
          */
          public?List?getAllEmployee(String?queryString,?String?queryCon,String?startRow,String?num)?{
          ??List?list?=?new?ArrayList();
          ??String?sql?=?null;
          ??if?(queryString?==?null?||?queryString.equals(""))?{
          ???sql?=?"select?*?from?employee,dept?"?+
          ?????"where?dept.Id?=?employee.deptId?"?+
          ?????"order?by?employee.id?asc"+?"?limit?"+startRow+","+num;
          ??}?else?{
          ???sql?=?"select?*?from?employee,dept?"?+
          ?????"where?dept.Id?=?employee.deptId?order?by?employee."
          ?????+?queryString?+?"?"?+?queryCon?+?"?limit?"+startRow+","+num;
          ??}
          ??Employee?employee?=?null;
          ??Database?db?=?new?Database();
          ??ResultSet?rs?=?db.executeQuery(sql);
          ??try?{
          ???while?(rs.next())?{
          ????String?id?=?(String)?rs.getString("employee.id");
          ????String?name?=?(String)?rs.getString("employee.name");
          ????String?deptId?=?(String)?rs.getString("employee.deptId");
          ????String?deptName?=?(String)?rs.getString("dept.deptName");
          ????employee?=?new?Employee();
          ????employee.setId(id);
          ????employee.setName(name);
          ????employee.setDeptId(deptId);
          ????employee.setDeptName(deptName);
          ????list.add(employee);
          ???}
          ??}?catch?(SQLException?e)?{
          ???e.printStackTrace();
          ??}
          ??db.close();
          ??return?list;
          ?}
          這里我用了hibernate進(jìn)行數(shù)據(jù)庫操作,你也可以用jdbc進(jìn)行操作,情況類似。

          二,根據(jù)總的頁數(shù),當(dāng)前頁
          這樣的話構(gòu)造函數(shù)應(yīng)該寫成:
          public?PageBean(int?totalRows,int?currentPage)?{
          ??this.totalRows?=?totalRows;
          ??this.currentPage?=?currentPage;
          ??if(currentPage?<?2)
          ???hasPreviousPage?=?false;
          ??else
          ???hasPreviousPage?=?true;
          ??if?((totalRows?%?pageRecorders)?==?0)?{
          ???totalPages?=?totalRows?/?pageRecorders;
          ??}?else?{
          ???totalPages?=?totalRows?/?pageRecorders?+?1;
          ??}
          ??if?(currentPage?<?totalPages)?{
          ???hasNextPage?=?true;
          ???nextPage?=?currentPage?+?1;
          ???pageStartRow?=?(currentPage?-?1)*pageRecorders;
          ???this.pageEndRow?=?pageStartRow?+?pageRecorders;
          ??}?else?if(currentPage?==?totalPages){
          ???pageStartRow?=?(currentPage?-?1)*pageRecorders;
          ???this.pageEndRow?=?totalRows;
          ???hasNextPage?=?false;
          ???nextPage?=?currentPage;
          ??}
          ??if(currentPage?<?2){
          ???previousPage?=?currentPage;
          ???hasPreviousPage?=?false;
          ??}else?if(currentPage?>?1){
          ???previousPage?=?currentPage-1;
          ???hasPreviousPage?=?true;
          ??}?
          ?}

          在action中應(yīng)該寫成
          if(currentPage?==?null){
          ????pb?=?new?PageBean(totalRows);
          ????session.removeAttribute("page");
          ????queryString?=?employeeForm.getQueryString();
          ????queryCon?=?employeeForm.getQueryCon();
          ????session.setAttribute("queryString",queryString);
          ????session.setAttribute("queryCon",queryCon);???
          ????list?=?employeeDao.getAllEmployee(queryString,?queryCon,
          ??????String.valueOf(pb.getPageStartRow()),
          ??????String.valueOf(pb.getPageRecorders()));
          ????}
          ???else{
          ????pb?=?new?PageBean(totalRows,Integer.parseInt(currentPage));
          ????queryString?=?employeeForm.getQueryString();
          ????queryCon?=?employeeForm.getQueryCon();
          ????session.setAttribute("queryString",queryString);
          ????session.setAttribute("queryCon",queryCon);???
          ????list?=?employeeDao.getAllEmployee(queryString,?queryCon,
          ??????String.valueOf(pb.getPageStartRow()),
          ??????String.valueOf(pb.getPageRecorders()));
          ???}
          ??session.setAttribute("page",pb);????????
          ??request.setAttribute("admin",?"admin");
          ??request.setAttribute("employee",?list);
          ??return?mapping.findForward("showlist");

          在jsp中應(yīng)該寫成:
          <logic:equal?name="page"?property="hasNextPage"?value="true">
          <a?href="List.do?currentPage=<bean:write?name="page"?property="nextPage"/>">
          nextPage
          </a>
          </logic:equal>
          <logic:equal?name="page"?property="hasPreviousPage"?value="true">
          ?|?
          <a?href="/test/List.do?currentPage=<bean:write?name="page"?property="previousPage"/>">
          PreviousPage
          </a>
          </logic:equal>
          數(shù)據(jù)庫查詢部分依然適用。



          盡管洋洋灑灑貼了一部分代碼,不過好像不太想看,包括我,也比較討厭看一些煩瑣的代碼,所以如果你想要源代碼進(jìn)行探討研究的話,歡迎隨時(shí)找我。那就總結(jié)一下這兩種方法吧
          首先這兩種方法都是取需要顯示的數(shù)據(jù)顯示,這樣,在數(shù)據(jù)庫龐大的情況下,比一次性把所有數(shù)據(jù)都取出來的效率要高。
          第一種方法是把PageBean存在了一個(gè)HttpSession中,在進(jìn)入到顯示列表的時(shí)候就進(jìn)行了初始化,在jsp頁面?zhèn)鬟f的參數(shù)action是固定的三個(gè)值:null,nextPage,previousPage.這樣雖然比較容易理解,但是我發(fā)現(xiàn)一個(gè)BUG,就是如果你按刷新,他也會翻頁,因?yàn)樗膗rl就是?.do?aciton=nextPage,這樣的話你傳進(jìn)去的action還是有一個(gè)值,這樣就會導(dǎo)致翻頁。
          第二種方法是考慮了第一種方法的BUG,在jsp頁面?zhèn)鬟f的參數(shù)currentPage的值是bean中的nextPage的值或者previousPage里的值,用了struts標(biāo)簽庫嵌套,把值賦予currentPage,這樣的話currentPage的值是:1,2,3,4...totalPages之間。這樣的話你即使按刷新按鈕,他也是當(dāng)前頁,因?yàn)樗膗rl就是.do?currentPage=someNumber(someNumber是1到totalPages中的一個(gè)值)。但是這樣的話Pagebean在每次訪問的時(shí)候都要重新生成一個(gè)對象,該對象也是根據(jù)totalRows(總數(shù)據(jù)數(shù)),currentPage(當(dāng)前頁數(shù))進(jìn)行構(gòu)造,從而設(shè)置其他的一些屬性。個(gè)人比較推薦第二種方法。
          主站蜘蛛池模板: 黔南| 门头沟区| 德昌县| 乌兰浩特市| 永年县| 察隅县| 于都县| 扎囊县| 舟曲县| 行唐县| 延寿县| 崇阳县| 都兰县| 闸北区| 宾阳县| 宁远县| 营山县| 潮安县| 寿宁县| 任丘市| 兴海县| 贵州省| 宿松县| 通州区| 盐池县| 竹山县| 云林县| 牟定县| 常熟市| 久治县| 鸡东县| 凯里市| 台中市| 射阳县| 浪卡子县| 台州市| 潮安县| 安岳县| 荔波县| 理塘县| 吉隆县|