首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

JSP 分頁查詢:解決記錄數非頁面大小整數倍時的指針越界異常

     編輯:程式設計綜合問答

問題復現

13 條記錄,頁面大小 4 → 應 4 頁。原代碼計算 `abs = (i-1)*pageSize+1`,第 4 頁 `abs=13`,但 `rs.absolute(13)` 拋出異常,原因是 ResultSet 游標從 1 開始,最大合法值為記錄總數(13),理論上合法,但具體驅動實現可能不支持跳轉到最後一條之後的位置,或游標類型非 `TYPE_SCROLL_INSENSITIVE`。

根因分析

  • 使用 `rs.absolute()` 要求 ResultSet 必須可滾動(`TYPE_SCROLL_INSENSITIVE` 或 `TYPE_SCROLL_SENSITIVE`),默認 `TYPE_FORWARD_ONLY` 不支持。
  • 即使可滾動,部分 JDBC 驅動對 `absolute(n)` 在邊界條件處理不一致。

最佳實踐:SQL 層面分頁(推薦)

-- MySQL
SELECT * FROM billRec
WHERE date BETWEEN '2015-09-15' AND '2015-09-30'
ORDER BY date
LIMIT ?, ?;  -- offset, pageSize

-- Oracle 12c+
SELECT * FROM (
    SELECT a.*, ROWNUM rn FROM (
        SELECT * FROM billRec WHERE date BETWEEN ... ORDER BY date
    ) a WHERE ROWNUM <= ?
) WHERE rn > ?;

若必須在 Java 層處理(不推薦)

List all = fetchAll(); // 一次性查出
int pageSize = 4;
int total = all.size();
int pageCount = (total + pageSize - 1) / pageSize;

for (int i = 1; i <= pageCount; i++) {
    int from = (i - 1) * pageSize;
    int to = Math.min(from + pageSize, total);
    List pageData = all.subList(from, to);
    // 輸出 pageData
}

補充:生成連續日期填充 0 的 SQL 方案

WITH RECURSIVE dates(d) AS (
    SELECT '2015-09-15' UNION ALL
    SELECT DATE_ADD(d, INTERVAL 1 DAY) FROM dates WHERE d < '2015-09-30'
)
SELECT d.date,
       COALESCE(b.money, 0) AS money,
       COALESCE(b.num, 0) AS num
FROM dates d
LEFT JOIN billRec b ON b.date = d.date
ORDER BY d.date;

(MySQL 8.0+ / PostgreSQL / SQL Server 支持 CTE 遞歸)

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved