龍行天下

            政 博
          隨筆 - 23, 文章 - 0, 評(píng)論 - 12, 引用 - 0
          數(shù)據(jù)加載中……

          Struts+Hibernate開(kāi)發(fā)實(shí)踐 分頁(yè)的實(shí)現(xiàn)

          在進(jìn)行web應(yīng)用開(kāi)發(fā)的時(shí)候經(jīng)常要進(jìn)行分頁(yè)處理,經(jīng)??吹揭恍┤嗽趩?wèn)分頁(yè)處理的問(wèn)題,現(xiàn)在我把自己的處理方法寫(xiě)在這兒,希望能對(duì)需要進(jìn)行分頁(yè)處理的朋友有所幫助。

          一、在struts中分頁(yè)有兩種結(jié)構(gòu):
          ??? 1. 在Action中通過(guò)DAO查詢出所有的記錄,然后加到session或request對(duì)象中,傳到客戶端,由JSP進(jìn)行分頁(yè)。這種方法對(duì)于在數(shù)據(jù)量少的時(shí)候很方便,也不影響速度。
          ??? 2.在Action中每次通過(guò)DAO只查詢出一頁(yè)的記錄,再傳給JSP頁(yè)面。這種結(jié)構(gòu)對(duì)于數(shù)據(jù)量大的程序很好,但對(duì)于數(shù)據(jù)量小的情況,會(huì)增加對(duì)服務(wù)器的請(qǐng)求,加大服務(wù)器的負(fù)載。
          ?????
          二、Hibernate查詢
          ??? 由于在Hibernate中直接提供了對(duì)數(shù)據(jù)庫(kù)定點(diǎn)定量的查詢方法,所以我采用的是第2種方法。

          如:
          從第1萬(wàn)條開(kāi)始取出100條記錄
          Query q = session.createQuery("from Cat as c");
          q.setFirstResult(10000);
          q.setMaxResults(100);
          List l = q.list();

          三、具體實(shí)現(xiàn)

          ?1.Pager類

          package com.jpcf.db.helper;

          import java.math.*;

          public class Pager {
          ? private int totalRows; //總行數(shù)
          ? private int pageSize = 10; //每頁(yè)顯示的行數(shù)
          ? private int currentPage; //當(dāng)前頁(yè)號(hào)
          ? private int totalPages; //總頁(yè)數(shù)
          ? private int startRow; //當(dāng)前頁(yè)在數(shù)據(jù)庫(kù)中的起始行

          ? public Pager() {
          ? }

          ? public Pager(int _totalRows) {
          ??? totalRows = _totalRows;
          ??? totalPages=totalRows/pageSize;
          ??? int mod=totalRows%pageSize;
          ??? if(mod>0){
          ????? totalPages++;
          ??? }
          ??? currentPage = 1;
          ??? startRow = 0;
          ? }

          ? public int getStartRow() {
          ??? return startRow;
          ? }

          ? public int getTotalPages() {
          ??? return totalPages;
          ? }

          ? public int getCurrentPage() {
          ??? return currentPage;
          ? }

          ? public int getPageSize() {
          ??? return pageSize;
          ? }

          ? public void setTotalRows(int totalRows) {
          ??? this.totalRows = totalRows;
          ? }

          ? public void setStartRow(int startRow) {
          ??? this.startRow = startRow;
          ? }

          ? public void setTotalPages(int totalPages) {
          ??? this.totalPages = totalPages;
          ? }

          ? public void setCurrentPage(int currentPage) {
          ??? this.currentPage = currentPage;
          ? }

          ? public void setPageSize(int pageSize) {
          ??? this.pageSize = pageSize;
          ? }

          ? public int getTotalRows() {
          ??? return totalRows;
          ? }

          ? public void first() {
          ??? currentPage = 1;
          ??? startRow = 0;
          ? }

          ? public void previous() {
          ??? if (currentPage == 1) {
          ????? return;
          ??? }
          ??? currentPage--;
          ??? startRow = (currentPage - 1) * pageSize;
          ? }

          ? public void next() {
          ??? if (currentPage < totalPages) {
          ????? currentPage++;
          ??? }
          ??? startRow = (currentPage - 1) * pageSize;
          ? }

          ? public void last() {
          ??? currentPage = totalPages;
          ??? startRow = (currentPage - 1) * pageSize;
          ? }

          ? public void refresh(int _currentPage) {
          ??? currentPage = _currentPage;
          ??? if (currentPage > totalPages) {
          ????? last();
          ??? }
          ? }

          }

          Pager類用于計(jì)算首頁(yè)、前一頁(yè)、下一頁(yè)、尾頁(yè)的在數(shù)據(jù)庫(kù)中的起始行,當(dāng)前的頁(yè)碼。

          2.PagerHelp類

          package com.jpcf.db.helper;

          import javax.servlet.http.*;

          public class PagerHelper {

          ? public static Pager getPager(HttpServletRequest httpServletRequest,int totalRows) {

          ??? //定義pager對(duì)象,用于傳到頁(yè)面
          ??? Pager pager = new Pager(totalRows);

          ??? //從Request對(duì)象中獲取當(dāng)前頁(yè)號(hào)
          ??? String currentPage = httpServletRequest.getParameter("currentPage");

          ??? //如果當(dāng)前頁(yè)號(hào)為空,表示為首次查詢?cè)擁?yè)
          ??? //如果不為空,則刷新pager對(duì)象,輸入當(dāng)前頁(yè)號(hào)等信息
          ??? if (currentPage != null) {
          ????? pager.refresh(Integer.parseInt(currentPage));
          ??? }

          ??? //獲取當(dāng)前執(zhí)行的方法,首頁(yè),前一頁(yè),后一頁(yè),尾頁(yè)。
          ??? String pagerMethod = httpServletRequest.getParameter("pageMethod");

          ??? if (pagerMethod != null) {
          ????? if (pagerMethod.equals("first")) {
          ??????? pager.first();
          ????? } else if (pagerMethod.equals("previous")) {
          ??????? pager.previous();
          ????? } else if (pagerMethod.equals("next")) {
          ??????? pager.next();
          ????? } else if (pagerMethod.equals("last")) {
          ??????? pager.last();
          ????? }
          ??? }
          ??? return pager;
          ? }
          }

          PageHelper這個(gè)類,我不用說(shuō)應(yīng)該也知道用來(lái)干嘛了

          3.DAO類

          package com.jpcf.db.dao;

          import com.jpcf.db.model.*;
          import com.jpcf.db.helper.HibernateUtil;
          import net.sf.hibernate.*;
          import java.util.*;
          import com.jpcf.db.controller.*;

          public class VehiclePropertyDAO {

          ? public Collection findWithPage(int pageSize, int startRow) throws HibernateException {
          ??? Collection vehicleList = null;
          ??? Transaction tx = null;
          ??? try {
          ????? Session session = HibernateUtil.currentSession();
          ????? tx = session.beginTransaction();
          ????? Query q = session.createQuery("from VehicleProperty vp");
          ????? q.setFirstResult(startRow);
          ????? q.setMaxResults(pageSize);
          ????? vehicleList = q.list();
          ????? tx.commit();
          ??? } catch (HibernateException he) {
          ????? if (tx != null) {
          ??????? tx.rollback();
          ????? }
          ????? throw he;
          ??? } finally {
          ????? HibernateUtil.closeSession();
          ??? }
          ??? return vehicleList;
          ? }

          ? public int getRows(String query) throws HibernateException {
          ??? int totalRows = 0;
          ??? Transaction tx = null;
          ??? try {
          ????? Session session = HibernateUtil.currentSession();
          ????? tx = session.beginTransaction();
          ????? totalRows = ((Integer) session.iterate(query).next()).intValue();
          ????? tx.commit();
          ??? } catch (HibernateException he) {
          ????? if (tx != null) {
          ??????? tx.rollback();
          ????? }
          ????? throw he;
          ??? } finally {
          ????? HibernateUtil.closeSession();
          ??? }

          ??? return totalRows;
          ? }

          }
          DAO類我就貼這些分頁(yè)需要的代碼了。
          “from VehicleProperty vp”也可以用一個(gè)參數(shù)傳進(jìn)來(lái),有興趣的自己改一下吧

          4.Action

          下面是在Action中用到的代碼:
          ? public ActionForward execute(ActionMapping actionMapping,
          ???????????????????????????????????? ActionForm actionForm,
          ???????????????????????????????????? HttpServletRequest httpServletRequest,
          ???????????????????????????????????? HttpServletResponse httpServletresponse) {
          ???? Collection clInfos = null;//用于輸出到頁(yè)面的記錄集合
          ???? int totalRows;//記錄總行數(shù)
          ???? VehiclePropertyDAO vehicleDAO = new VehiclePropertyDAO();

          ??? //取得當(dāng)前表中的總行數(shù)
          ??? try {
          ????? totalRows = vehicleDAO.getRows("select count(*) from VehicleProperty");
          ??? } catch (Exception ex) {
          ????? servlet.log(ex.toString());
          ????? return actionMapping.findForward(Constants.FAILURE);
          ??? }

          ??? //通過(guò)PagerHelper類來(lái)獲取用于輸出到頁(yè)面的pager對(duì)象
          ??? Pager pager=PagerHelper.getPager(httpServletRequest,totalRows);

          ??? //取出從startRow開(kāi)始的pageSize行記錄
          ??? try {
          ????? clInfos = vehicleDAO.findWithPage(pager.getPageSize(), pager.getStartRow());
          ??? } catch (Exception ex) {
          ????? servlet.log(ex.toString());
          ????? return actionMapping.findForward(Constants.FAILURE);
          ??? }

          ??? //把輸出的記錄集和pager對(duì)象保存到request對(duì)象中
          ??? httpServletRequest.setAttribute("CLINFOS", clInfos);
          ??? httpServletRequest.setAttribute("PAGER", pager);

          ??? return actionMapping.findForward(Constants.SUCCESS);
          ? }

          ?? 查詢語(yǔ)句select count(*) from VehicleProperty 也可以換成你需要的任意的條件(select count(*)?

          from VehicleProperty where ..)


          5.JSP頁(yè)面使用

          下面就是在JSP中的應(yīng)用了:

          <td colspan="8" align="right" class="head">
          ?? 第<bean:write name="PAGER" property="currentPage"/>頁(yè)?
          ?? 共<bean:write name="PAGER" property="totalPages"/>頁(yè)?
          ?? <html:link action="/bussiness/clInfo/queryWithPage.do?method=queryWithPage&pageMethod=first"?
          paramName="PAGER" paramProperty="currentPage" paramId="currentPage">首頁(yè)</html:link>
          ?? <html:link action="/bussiness/clInfo/queryWithPage.do?method=queryWithPage&pageMethod=previous"?
          paramName="PAGER" paramProperty="currentPage" paramId="currentPage">上一頁(yè)</html:link>
          ?? <html:link action="/bussiness/clInfo/queryWithPage.do?method=queryWithPage&pageMethod=next"?
          paramName="PAGER" paramProperty="currentPage" paramId="currentPage">下一頁(yè)</html:link>
          ?? <html:link action="/bussiness/clInfo/queryWithPage.do?method=queryWithPage&pageMethod=last"?
          paramName="PAGER" paramProperty="currentPage" paramId="currentPage">尾頁(yè)</html:link>
          </td>

          ?? 解釋一下這一行:"/bussiness/clInfo/queryWithPage.do?method=queryWithPage&pageMethod=first
          method=queryWithPage 是由于我的Action繼承的是DispatchAction,需要一個(gè)method參數(shù)
          pageMethod=first 是用來(lái)在PageHelper類中判斷執(zhí)行哪個(gè)操作

          四、總結(jié)

          ??? 我做的這個(gè)也只是一個(gè)借鑒,還有很多沒(méi)有實(shí)現(xiàn)的,比如還可以加一下 go 直接到第n頁(yè)的功能。
          ??? 其實(shí)最關(guān)鍵的是把當(dāng)前頁(yè)號(hào)和要執(zhí)行的是功能(上一頁(yè),下一頁(yè))的參數(shù)從頁(yè)面?zhèn)鬟M(jìn)來(lái),在Action中就可以根據(jù)這兩個(gè)參數(shù)去取下一個(gè)頁(yè)面上要顯示的記錄集了。

          posted on 2006-05-03 20:04 feingto 閱讀(415) 評(píng)論(0)  編輯  收藏 所屬分類: Java Web

          主站蜘蛛池模板: 施秉县| 札达县| 万荣县| 万年县| 灵石县| 金沙县| 曲沃县| 微山县| 保靖县| 论坛| 耿马| 霍州市| 福州市| 昆山市| 太仓市| 同江市| 白城市| 都兰县| 冕宁县| 揭西县| 平邑县| 鄂伦春自治旗| 丰原市| 石渠县| 开阳县| 桦南县| 八宿县| 上高县| 军事| 霍山县| 丰顺县| 怀仁县| 鲁山县| 得荣县| 淳化县| 房山区| 正蓝旗| 古交市| 德惠市| 靖宇县| 卢湾区|