2011年3月5日 星期六

JSP 教學 - 運用 Javabean 製作分頁功能

一般在製作 JSP 的分頁功能時,最簡單的想法應該是直接寫一些 Scriptlet

並透過參數的方式達到分頁以及由資料表中選取所需的資料

不過往往會在 JSP 裡產生過多的 Java 程式碼,所以可以透過 JavaBean 的特性

並透過 EL 和 JSTL 的運用來減少 JSP 裡的過多的 Java 程式,簡單說就是以 JavaBean 當作一個工具

首先以下範例為一個購物網站,假設在資料庫中有 20 筆資料,而網站內容是每頁展示9筆

程式的主要架構是將先是商品的網頁嵌入在一個 iframe,且此網頁必由 servlet 轉送而來

為什麼一定要從 servlet 轉送過來,因為我需要在 Servlet 內執行一些 SQL 語句和 javabean 的處理

以下來看看這個 Servlet 程式 listgoods.java
package org.controller;
import org.tool.Pagebean;
import org.model.Good;
import org.dao.GoodDAO;
import java.io.IOException;
import java.util.ArrayList;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class listgoods extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException 
    {
        request.setCharacterEncoding("UTF-8");
        int nowPageNumber = 1;  //目前頁數

        if(request.getParameter("nowP") != null){  //檢查看看是否有 nowP 參數
            nowPageNumber = Integer.parseInt(request.getParameter("nowP"));
        }else{
            nowPageNumber = 1; //代表目前請求的是第一頁
        }
        Pagebean pagebean = new Pagebean();   //Pagebean 為產生分頁程式碼的 JavaBean 
        pagebean.setPageLink(nowPageNumber);   //產生分頁功能的程式碼
        //查詢當前頁面所需的資料,透過 GoodDAO 實現
        ArrayList goods = new GoodDAO().getAllGoods(nowPageNumber);  

        request.setAttribute("goods", goods);   //設定屬性,方便在JSP 顯示商品
        request.setAttribute("pagebean", pagebean);   //設定屬性,方便在JSP 顯示分頁功能
        //重新導向到 listgoods.jsp 以顯示商品內容
        request.getRequestDispatcher("listgoods.jsp").forward(request, response);
    }
}

接下來看看 Pagebean.java
package org.tool;
import org.dao.GoodDAO;
public class Pagebean
{
    private String pageLink = "";
 
    public void setPageLink(int page)  //注意連結(a link)是如何寫的
    {
        int allGoods = new GoodDAO().getGoodsCount();  //透過 GoodDAO 取得資料庫中有幾筆資料
        int allP = 0;   //allP 代表呈獻所有資料所需的頁數
        allP = allGoods / 9;   //每頁呈現9項商品
        if(allGoods % 9 != 0){  //如果除以9有逾數 代表還要在+1頁
            allP++;
        }
        pageLink += "<table border='0' cellpadding='2' cellspacing='0'>";  //table
        
        if(page != 1){ //如果當前頁不等於第一頁,即可顯示"上一頁"
            pageLink += "<tr><td><a href='listgoods?nowP=" + String.valueOf(page-1) + "'>上一頁</a></td>";
        }
        pageLink += "";

        for(int i=1;i<=allP;i++){  //最多顯示10頁, 如果總頁數超過10頁則跳出
            if(i > 10) break;

                pageLink += "<a href='listgoods?nowP=" + String.valueOf(i) + "'>" + String.valueOf(i) + "</a>";

        }

        if(allP > 10){  //總頁數超過10頁時,以 "...." 再加上最後一頁的編碼

            pageLink += "....";

            pageLink += "<a href='listgoods?nowP=" + String.valueOf(allP) + "'>" + String.valueOf(allP) + "</a>";

        }

        pageLink += "</td>";

        if(page != allP){  //當前頁不為最後一頁時, 即可顯示"下一頁"

            pageLink += "<td><a href='listgoods?nowP=" + String.valueOf(page+1) + "'>下一頁</a></td>";

        }

        pageLink += "</tr>";

        pageLink += "</table>";

    }

    public String getPageLink(){

        return pageLink;

    }

}


接著在看看 GoodDAO.java 的 getAllGoods() 方法和 getGoodsCount()方法
//....
public ArrayList getAllGoods(int page)  //取得所有商品
{
    //每頁顯示 9 筆資料
    //所以是 0-8 9-17 18-....   資料庫是從0開始算
    int n = (page-1)*9;


    //因為我使用的資料庫是 MYSQL 所以可以透過 limit語法 限定由哪個位置開始抓取多少筆資料
    //以下的 db 是我專案內專門處理資料庫的一個工具類,所以此處依你的需求更換
    db.exceuteQueUpd("SELECT * FROM goods ORDER BY uptime DESC limit "  + n + ",9", new Object[]{});
    ArrayList list = new ArrayList();
    try{
 Good good;
 ResultSet result = db.getResult();
 while(result.next())
 {
     good = new Good();  //Good 物件的程式碼省略
     good.setId(result.getInt("id"));
     good.setViewpic(result.getString("viewpic"));
     good.setName(result.getString("name"));
            good.setPrice(result.getInt("price"));
     good.setStorenum(result.getInt("storenum"));
     good.setUptime(result.getDate("uptime"));
     good.setMaaker(result.getString("maker"));
     good.setInfo(result.getString("info"));
            list.add(good);
        }
    }catch(java.sql.SQLException e){
        System.out.println(e.getMessage());
        list = null;
    }
    return list;
}
public int getGoodsCount()  //取得資料庫中的總筆數
{
    db.exceuteQueUpd("SELECT * FROM goods", new Object[]{});
    try{
        ResultSet result = db.getResult();
        result.last();
        return result.getRow();
    }catch(java.sql.SQLException e){
        System.out.println(e.getMessage());
        return 0;
    }
}

最後由於我是使用一JSP (main.jsp) 裡面包含的 iframe , iframe 裡面則未顯示商品的網頁內容

以下為 main.jsp 的其中一段
<iframe id="listgoods" src="listgoods" width="100%" frameborder="0" scrolling="no"></iframe>

listgoods 指向的就是後台的 listgoods.java 的 servlet 程式


最後看看沒有半點 Java 程式的 listgood.jsp


<table width="99%" border="0" cellspacing="5" cellpadding="5">    
    <c:choose>
        <c:when test="${requestScope.goods ne null}">
            <c:set var="allgoods" value="${requestScope.goods}" />
            <c:forEach var="aGood" items="${allgoods}" varStatus="Loopcount">
                <c:if test="${Loopcount.count%3 eq 1}" >
                    <tr>
                </c:if>
                    <td>
                        <img src="images/${aGood.viewpic}" width="150" height="150" /><br />
                        商品名稱 : ${aGood.name}<br />
                        商品價格 : ${aGood.price}<br />
                    </td>
                <c:if test="${Loopcount.count%3 eq 0}">
                    </tr>
                </c:if>
            </c:forEach>
            <tr>
                <td colspan="4">${requestScope.pagebean.pageLink}</td>
            </tr>
        </c:when>
        <c:otherwise>
            //資料庫發生錯誤
        </c:otherwise>
    </c:choose>
</table>     

沒有留言:

張貼留言