page),預設第 1 頁ResultSet (TYPE_SCROLL_INSENSITIVE, CONCUR_READ_ONLY)rs.last() 移至末尾取得總筆數 getRow()(total + pageSize - 1) / pageSizers.absolute((page-1)*pageSize + 1) 定位到當頁首筆pageSize 次 rs.next() 輸出資料<%@ page import="java.sql.*" contentType="text/html; charset=UTF-8" %>
<%
// 1. 參數處理
int pageSize = 2;
String pageParam = request.getParameter("page");
int page = (pageParam == null) ? 1 : Math.max(1, Integer.parseInt(pageParam));
// 2. 資料庫連線 (生產環境請用連線池)
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
Connection conn = DriverManager.getConnection(
"jdbc:oracle:thin:@linux:1521:ora4cweb", "hzq", "hzq");
Statement stmt = conn.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet rs = stmt.executeQuery("SELECT name, age FROM test");
// 3. 總筆數與總頁數
rs.last();
int total = rs.getRow();
int totalPages = (total + pageSize - 1) / pageSize;
if (page > totalPages) page = totalPages;
// 4. 定位到當頁起始列
rs.absolute((page - 1) * pageSize + 1);
%>
<html><body>
<table border="1" cellpadding="5">
<tr><th>姓名</th><th>年齡</th></tr>
<%
int count = 0;
while (count < pageSize && !rs.isAfterLast()) {
%>
<tr><td><%=rs.getString(1)%></td><td><%=rs.getString(2)%></td></tr>
<%
rs.next();
count++;
}
%>
</table>
第 <%=page%> 頁 / 共 <%=totalPages%> 頁
<% if (page < totalPages) { %> <a href="?page=<%=page+1%>">下一頁</a> <% } %>
<% if (page > 1) { %> <a href="?page=<%=page-1%>">上一頁</a> <% } %>
</body></html>
<%
rs.close(); stmt.close(); conn.close();
%>
| 技術 | 說明 | 注意事項 |
|---|---|---|
TYPE_SCROLL_INSENSITIVE | 可捲動、不反映他人提交的更新 | Oracle 驅動需支援;MySQL/PostgreSQL 同樣支援 |
CONCUR_READ_ONLY | 唯讀結果集,效能較好 | 不可更新 |
rs.last() / getRow() | 取得總筆數 | 需將游標移至末尾,大結果集可能較慢 |
rs.absolute(n) | 直接跳至第 n 列 (1-based) | 高效隨機存取,避免迴圈 next() |
rs.isAfterLast() | 判斷是否超過最後一列 | 配合計數器控制輸出筆數 |
SELECT * 再 last():大表先 SELECT COUNT(*) 取總數,再 LIMIT/OFFSET 或 ROWNUM 分頁查詢,減少網路傳輸與記憶體佔用。SELECT * FROM test ORDER BY id
OFFSET :offset ROWS FETCH NEXT :pageSize ROWS ONLY;
LIMIT :pageSize OFFSET :offset。DriverManager。AutoCloseable) 確保連線歸還。// Controller (Spring MVC)
@GetMapping("/users")
public String list(@RequestParam(defaultValue="1") int page,
@RequestParam(defaultValue="10") int size, Model model) {
Page p = userService.findPage(page, size); // Service 呼叫 Repository 分頁查詢
model.addAttribute("page", p);
return "user/list"; // Thymeleaf/JSP 渲染
}
可捲動結果集 (TYPE_SCROLL_INSENSITIVE) 實現分頁是 JDBC 2.0 經典技巧,適合中小資料量、快速原型。大規模系統請改用 資料庫原生分頁語法 (OFFSET/FETCH, LIMIT) 搭配 連線池、Service/Repository 分層、前端模板引擎,實現高效能、可維護的分頁功能。