首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

JSP + MySQL 分頁查詢實作範例:JDBC Scrollable ResultSet 與手動計算總頁數

     編輯:MySQL 資料庫相關知識

早期 JSP + MySQL 分頁經典寫法:使用 TYPE_SCROLL_INSENSITIVE 游標定位、手動計算總筆數/總頁數、前後頁連結產生。現代建議改用 LIMIT offset, size。

環境準備

  • MySQL Connector/J Jar 加入 CLASSPATH
  • 資料庫 test、表 note(name VARCHAR)

JSP 核心程式碼

<%@ page contentType="text/html;charset=gb2312" import="java.sql.*" %>
<%
  int pageSize = 2;
  String strPage = request.getParameter("page");
  int currentPage = (strPage == null) ? 1 : Integer.parseInt(strPage);
  if (currentPage < 1) currentPage = 1;

  Class.forName("org.gjt.mm.mysql.Driver").newInstance();
  Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/test");
  Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);

  // 1. 取得總筆數
  ResultSet rsCount = stmt.executeQuery("SELECT COUNT(*) FROM note");
  rsCount.next();
  int totalRows = rsCount.getInt(1);
  int totalPages = (totalRows + pageSize - 1) / pageSize;
  if (currentPage > totalPages) currentPage = totalPages;

  // 2. 定位到起始列 (Scrollable ResultSet 方式)
  ResultSet rs = stmt.executeQuery("SELECT name FROM note");
  rs.absolute((currentPage - 1) * pageSize + 1);

  // 3. 輸出當頁資料
  for (int i = 0; i < pageSize && !rs.isAfterLast(); i++) {
    out.println(rs.getString("name") + "<br>");
    rs.next();
  }

  // 4. 產生分頁連結
  for (int p = 1; p <= totalPages; p++) {
    if (p == currentPage) out.print("[" + p + "] ");
    else out.print("<a href='?page=" + p + "'>" + p + "</a> ");
  }

  rs.close(); rsCount.close(); stmt.close(); conn.close();
%>

關鍵技術點

⚠️ 效能缺陷與現代改寫

  • 全表掃描:SELECT * FROM note 讀取全表再定位,資料量大極慢
  • 雙重查詢:COUNT(*) + 完整結果集
  • 游標資源佔用:Scrollable ResultSet 需伺服器端緩衝

現代標準分頁 (MySQL 3.23+ / 所有版本)

-- 第 1 頁 (0-based offset)
SELECT name FROM note LIMIT 0, 2;

-- 第 N 頁
SELECT name FROM note LIMIT (N-1)*pageSize, pageSize;

-- 總筆數 (可用 SQL_CALC_FOUND_ROWS + FOUND_ROWS() 優化)
SELECT SQL_CALC_FOUND_ROWS name FROM note LIMIT 0, 2;
SELECT FOUND_ROWS();  -- 回傳無 LIMIT 時總筆數

結語

Scrollable ResultSet 分頁是 JDBC 1.x/2.x 時代的產物。現代專案務必使用 LIMIT offset, size,配合 SQL_CALC_FOUND_ROWS 或獨立 COUNT(*) (配合覆蓋索引極快)。大資料量深分頁 (offset > 100k) 改用 Keyset Pagination (Seek Method):WHERE id > last_seen_id ORDER BY id LIMIT 20。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
技術說明
TYPE_SCROLL_INSENSITIVE可隨意移動游標 (absolute()/relative()),不反映後續資料變更
absolute(n)移動到第 n 列 (1-based)
isAfterLast()判斷是否超過最後一列
手動 COUNT(*)必須額外查詢總筆數