JDBC在Java Web中的應用——分頁查詢


分頁查詢

通過JDBC實現分頁查詢的方法有很多種,而且不同的數據庫機制也提供了不同的分頁方式,在這里介紹兩種非常典型的分頁方法。

  1. 通過ResultSet的光標實現分頁

  通過ResultSet的光標實現分頁,優點是在各種數據庫上通用,缺點是占用大量資源,不適合數據量大的情況。

  2. 通過數據庫機制進行分頁

  很多數據庫自身都提供了分頁機制,如SQL Server中提供的top關鍵字,MySQL數據庫中提供的limit關鍵字,它們都可以設置數據返回的記錄數。

  通過各種數據庫的分頁機制實現分頁查詢,其優點是減少數據庫資源的開銷,提高程序的性能;缺點是只針對某一種數據庫通用。

說明:由於通過ResultSet的光標實現數據分頁存在性能方面的缺陷,所以,在實際開發中,很多情況下都是采用數據庫提供的分頁機制來實現分頁查詢功能。

例1.1 通過MySQL數據庫提供的分頁機制,實現商品信息的分頁查詢功能,將分頁數據顯示在JSP頁面中。

(1)創建名稱為Product的類,用於封裝商品信息,該類是商品信息的JavaBean。關鍵代碼如下:

 

package com.cn.gao;

public class Product {
    public static final int PAGE_SIZE=2; //每頁記錄數
    private int id;            //編號
    private String name;      //名稱
    private double price;    //價格
    private int num;        //數量
    private String unit;   //單位
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }
    public int getNum() {
        return num;
    }
    public void setNum(int num) {
        this.num = num;
    }
    public String getUnit() {
        return unit;
    }
    public void setUnit(String unit) {
        this.unit = unit;
    }

}

技巧:在Java語言中,如果定義了靜態的final類型變量,通常情況下將這個變量大寫。該種編寫方式是一種規范,能夠很容易地與其它類型的變量進行區分。

(2) 創建名稱為ProductDao的類,主要用於封裝商品對象的數據庫相關操作。在ProduceDao類中,首先編寫getConnection()方法,用於創建數據庫連接Connnection對象,其關鍵代碼如下:

/**
     * 獲取數據庫連接
     * @return Connection 對象
     */
    public Connection getConnection(){
        Connection conn=null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            String url = "jdbc:mysql://localhost:3306/test";
            String user = "root";
            String password = "1234";
            conn=DriverManager.getConnection(url, user, password);
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return conn;
    }

然后創建商品信息的分頁查詢方法find(),該方法包含一個page參數,用於傳遞要查詢的頁碼。關鍵代碼如下:

/**
     * 分頁查詢所有商品信息
     * @param page 頁數
     * @return List<Product>
     */
    public List<Product> find(int page){
        List<Product> list = new ArrayList<Product>();
        Connection conn = getConnection();
        String sql = "select* from tb_product order by id desc limit ?,?";
        try {
            PreparedStatement ps = conn.prepareStatement(sql);
            ps.setInt(1, (page-1)*Product.PAGE_SIZE);
            ps.setInt(2, Product.PAGE_SIZE);
            ResultSet rs = ps.executeQuery();
            while(rs.next()){
                Product p=new Product();
                p.setId(rs.getInt("id"));
                p.setName(rs.getString("name"));
                p.setNum(rs.getInt("num"));
                p.setPrice(rs.getDouble("price"));
                p.setUnit(rs.getString("unit"));
                list.add(p);
            }
            ps.close();
            conn.close();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return list;
    }

find()方法用於實現分頁查詢功能,該方法根據入口參數page傳遞的頁碼,查詢指定頁碼中的記錄,主要通過limit關鍵字實現。

說明:MySQL數據庫提供的limit關鍵字能夠控制查詢數據結果集起始位置及返回記錄的數量,它的使用方式如下:

limit arg1,arg2
參數說明:
arg1:用於指定查詢記錄的起始位置。
arg2:用於指定查詢數據所返回的記錄數。

在分頁查詢過程中,還需要獲取商品信息的總記錄數,用於計算商品信息的總頁數,該操作編寫在findCount()方法中。關鍵代碼如下:

/**
     * 查詢總記錄數
     * @return 總記錄數
     */
    public int findCount(){
        int count=0;
        Connection conn = getConnection();
        String sql = "select count(*) from tb_product";
        try {
            Statement sta = conn.createStatement();
            ResultSet rs = sta.executeQuery(sql);
            if(rs.next()){
                count = rs.getInt(1);  //對總記錄數賦值
            }
            rs.close();
            conn.close();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return count;        //返回總記錄數
    }

(3)創建名稱為FindServlet1的類,該類是分頁查詢商品信息的Servlet對象。在FindServlet1類中重寫doGet()方法,對分頁請求進行處理,其關鍵代碼如下:

package com.cn.gao;

import java.awt.print.Pageable;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class FindServlet1 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        int currPage=1;
        if(request.getParameter("page")!=null){
            currPage=Integer.parseInt(request.getParameter("page"));
        }
        ProductDao dao = new ProductDao();
        List<Product> list = dao.find(currPage);
        request.setAttribute("list", list);
        int pages;  //總頁數
        int count=dao.findCount(); //查詢總記錄數
        if(count%Product.PAGE_SIZE==0){
            pages=count/Product.PAGE_SIZE;
        }else{
            pages=count/Product.PAGE_SIZE+1;
        }
        StringBuffer sb = new StringBuffer();
        //通過循環構建分頁條
        for(int i=1;i<=pages;i++){
            if(i==currPage){   //判斷是否為當前頁
                sb.append("『"+i+"』");  //構建分頁條
            }else{
                sb.append("<a href='FindServlet1?page="+i+"'>"+i+"</a>"); //構建分頁條
            }
            sb.append(" ");
        }
        request.setAttribute("bar", sb.toString());;
        request.getRequestDispatcher("product_list.jsp").forward(request, response);
    }

}

技巧:分頁條在JSP頁面中是動態內容,每次查看新頁面都要重新構造,所以,實例中將分頁的構造放置到Servlet中,以簡化JSP頁面的代碼。

在獲取查詢結果集List與分頁條后,FindServlet1分別將這兩個對象放置到request中,將請求轉發到product_list.jsp頁面做出顯示。

(4)創建product_list.jsp頁面,該頁面通過獲取查詢結果集List與分頁條來分頁顯示商品信息數據。關鍵代碼如下:

 

<%@ page language="java" contentType="text/html; charset=GB18030"
    pageEncoding="GB18030"%>
<%@ page import="java.util.*" %>
<%@ page import="com.cn.gao.*" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GB18030">
<title>Insert title here</title>
</head>
<body>
    <table align="center" width="450" border="1">
        <tr>
            <td align="center" colspan="5">
                <h2>所有商品信息</h2>
            </td>
        </tr>
        <tr align="center">
            <td><b>ID</b></td>
            <td><b>商品名稱</b></td>
            <td><b>價格</b></td>
            <td><b>數量</b></td>
            <td><b>單位</b></td>
        </tr>
        <%
            List<Product> list=(List<Product>)request.getAttribute("list");
            for(Product p:list){
         %>
         <tr align="center">
             <td><%=p.getId() %></td>
             <td><%=p.getName() %></td>
             <td><%=p.getPrice() %></td>
             <td><%=p.getNum() %></td>
             <td><%=p.getUnit() %></td>
         </tr>
         <%
             }
          %>
          <tr>
              <td align="center" colspan="5">
                  <%=request.getAttribute("bar") %>
              </td>
          </tr>
    </table>
</body>
</html>

(5)編寫程序中的主頁面showproduct.jsp,在該頁面中編寫分頁查詢商品信息的超鏈接,指向FindServlet1。關鍵代碼如下:

<%@ page language="java" contentType="text/html; charset=GB18030"
    pageEncoding="GB18030"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GB18030">
<title>Insert title here</title>
</head>
<body>
    <a href="FindServlet1">查看所有商品信息</a>
</body>
</html>

 編寫完成該頁面后,部署運行項目,此時打開showproduct.jsp頁面,其效果如下圖所示:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM