首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> DB2 資料庫 >> DB2 教學

DB2 分頁查詢實戰:基於 FETCH FIRST 與 NOT IN 的 Java 實現

     編輯:DB2 教學

方案概覽

DB2 不像 MySQL 有 LIMIT offset, rows 或 Oracle 有 ROWNUM,其標準分頁方案結合 FETCH FIRST n ROWS ONLY 與 NOT IN (子查詢) 實現。本文提供完整的 Java/JDBC 參考實現,包含總記錄數統計、總頁數計算、當前頁邊界處理及動態 SQL 拼裝。

核心 SQL 模板

第一頁(第 1 頁)

SELECT * FROM stu.book <條件> FETCH FIRST <pageSize> ROWS ONLY

第 N 頁 (N > 1)

SELECT * FROM stu.book <條件>
AND booknum NOT IN (
    SELECT booknum FROM stu.book <條件> FETCH FIRST <(N-1)*pageSize> ROWS ONLY
)
FETCH FIRST <pageSize> ROWS ONLY

原理: 子查詢取出前 (N-1) 頁的主鍵,外層查詢排除這些主鍵,再取前 pageSize 條。

Java 完整實現代碼

public List<Book> queryPage(String condition, String CPage) {
    String sqlCount = "SELECT COUNT(*) FROM stu.book " + condition;
    int pageSize = 10;
    int curPage = 1;

    // 1. 解析並校驗頁碼
    if (CPage != null) {
        try { curPage = Integer.parseInt(CPage); }
        catch (NumberFormatException e) { curPage = 1; }
        if (curPage < 1) curPage = 1;
    }

    Connection con = null;
    PreparedStatement ps = null;
    ResultSet rs = null;
    List<Book> list = new ArrayList<>();

    try {
        con = Dao.getConn();

        // 2. 查總記錄數
        ps = con.prepareStatement(sqlCount);
        rs = ps.executeQuery();
        int totalRecords = 0;
        if (rs.next()) totalRecords = rs.getInt(1);

        // 3. 計算總頁數
        int totalPages = (totalRecords + pageSize - 1) / pageSize;
        if (curPage > totalPages) curPage = totalPages; // 防止越界

        // 4. 構建分頁 SQL
        String sql;
        if (curPage == 1) {
            sql = "SELECT * FROM stu.book " + condition + " FETCH FIRST " + pageSize + " ROWS ONLY";
        } else {
            int offset = (curPage - 1) * pageSize;
            sql = "SELECT * FROM stu.book " + condition +
                  " AND booknum NOT IN (SELECT booknum FROM stu.book " + condition +
                  " FETCH FIRST " + offset + " ROWS ONLY) " +
                  " FETCH FIRST " + pageSize + " ROWS ONLY";
        }
        System.out.println("執行 SQL: " + sql);

        // 5. 執行查詢並映射對象
        ps = con.prepareStatement(sql);
        rs = ps.executeQuery();
        while (rs.next()) {
            Book b = new Book();
            b.setBooknum(rs.getString(1));
            b.setBookname(rs.getString(2));
            b.setBookindate(rs.getString(3));
            b.setBorrower(rs.getString(4));
            b.setLenddate(rs.getString(5));
            b.setRemark(rs.getString(6));
            list.add(b);
        }
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        // 關閉資源 (省略具體 close 代碼)
    }
    return list;
}

關鍵點總結

  • 主鍵依賴: 方案假設 booknum 為唯一主鍵,若無主鍵需組合唯一鍵。
  • 性能考量: 深分頁時 NOT IN 子查詢掃描量大,海量數據建議改用游標、臨時表或 ROW_NUMBER() OVER() 窗口函數(DB2 9.7+ 支持)。
  • 條件復用: condition 變量需包含 WHERE 關鍵字(如 " WHERE status=1"),否則 SQL 語法錯誤。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved