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

JSP 分頁顯示實戰:Bootstrap + bootstrap-paginator 完整實現方案

     編輯:Java 綜合教學

JSP 分頁顯示實戰:Bootstrap + bootstrap-paginator 完整實現方案

在傳統 JSP 專案中實現美觀、功能完整的分頁,bootstrap-paginator 是一款輕量級的最佳選擇。本文提供基於 Bootstrap 3 的完整分頁實現,包含後端分頁邏輯、前端渲染、JS 初始化配置,以及 SQL Server/MySQL 分頁寫法差異說明。

效果預覽

支援首頁/末頁、上一頁/下一頁、頁碼跳轉、頁面大小切換、當前頁高亮、Tooltip 提示,完美適配 Bootstrap 3 風格。

後端分頁邏輯 (JSP 內嵌 Java 代碼)

<%@ page import="java.util.*, java.sql.*" %>
<%@ page import="com.example.model.Record, com.example.util.DBUtil" %>
<%
    final int pageSize = 20;
    request.setCharacterEncoding("UTF-8");
    response.setCharacterEncoding("UTF-8");
    response.setContentType("text/html;charset=UTF-8");
    
    // 1. 獲取並校驗頁碼
    String pageNoStr = request.getParameter("pageNoStr");
    int pageNo = 1;
    try {
        if (pageNoStr != null && !pageNoStr.isEmpty()) {
            pageNo = Integer.parseInt(pageNoStr);
            if (pageNo < 1) pageNo = 1;
        }
    } catch (NumberFormatException e) {
        pageNo = 1;
    }
    
    // 2. 查詢總記錄數 → 計算總頁數
    int totalPages = 1;
    try (Connection conn = DBUtil.getConnection();
         Statement stmt = conn.createStatement();
         ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM alldata")) {
        if (rs.next()) {
            int totalRecords = rs.getInt(1);
            totalPages = (totalRecords + pageSize - 1) / pageSize; // 向上取整
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }
    
    // 3. 邊界修正
    if (pageNo > totalPages) pageNo = totalPages;
    
    // 4. 查詢當前頁數據
    List<Record> records = new ArrayList<>();
    int startIndex = (pageNo - 1) * pageSize + 1;
    int endIndex = pageNo * pageSize;
    
    // SQL Server 分頁寫法(ROW_NUMBER)
    String sql = "SELECT * FROM (" +
        "SELECT ROW_NUMBER() OVER(ORDER BY data_taizhan_num, data_date ASC) AS rn, * FROM alldata" +
        ") AS temp WHERE rn BETWEEN ? AND ?";
    
    try (Connection conn = DBUtil.getConnection();
         PreparedStatement pstmt = conn.prepareStatement(sql)) {
        pstmt.setInt(1, startIndex);
        pstmt.setInt(2, endIndex);
        try (ResultSet rs = pstmt.executeQuery()) {
            while (rs.next()) {
                Record r = new Record();
                r.setTaizhan_num(rs.getString("data_taizhan_num"));
                r.setDate(rs.getTimestamp("data_date"));
                r.setTem(rs.getString("data_tem"));
                r.setHum(rs.getString("data_hum"));
                r.setPa(rs.getString("data_pa"));
                r.setRain(rs.getString("data_rain"));
                r.setWin_dir(rs.getString("data_win_dir"));
                r.setWin_sp(rs.getString("data_win_sp"));
                records.add(r);
            }
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }
%>

前端頁面結構

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>搜索記錄 - 分頁演示</title>
    <link rel="stylesheet" href="css/bootstrap.css">
    <link rel="stylesheet" href="css/recordSearchResult.css">
</head>
<body>
    <div class="container">
        <form class="form-area">
            <table class="table table-striped table-hover">
                <thead>
                    <tr>
                        <th>觀測台站</th>
                        <th>溫度(℃)</th>
                        <th>濕度(%)</th>
                        <th>壓強(hPa)</th>
                        <th>雨量(mm)</th>
                        <th>風向(°)</th>
                        <th>風速(m/s)</th>
                        <th>觀測時間</th>
                    </tr>
                </thead>
                <tbody>
                    <%
                        if (records == null || records.isEmpty()) {
                            out.println("<tr><td colspan='8' class='text-center'><h4>沒有符合要求的記錄</h4></td></tr>");
                        } else {
                            for (Record r : records) {
                    %>
                    <tr>
                        <td><%= r.getTaizhan_num() %></td>
                        <td><%= r.getTem() %></td>
                        <td><%= r.getHum() %></td>
                        <td><%= r.getPa() %></td>
                        <td><%= r.getRain() %></td>
                        <td><%= r.getWin_dir() %></td>
                        <td><%= r.getWin_sp() %></td>
                        <td><%= r.getDate() %></td>
                    </tr>
                    <% } } %>
                </tbody>
            </table>
            
            <!-- 分頁容器 -->
            <div class="text-center">
                <ul class="pagination" id="paginator"></ul>
            </div>
        </form>
    </div>
    
    <script src="js/jquery-1.12.3.min.js"></script>
    <script src="js/bootstrap.min.js"></script>
    <script src="js/bootstrap-paginator.min.js"></script>
    <script>
        var options = {
            bootstrapMajorVersion: 3,  // 關鍵:指定 Bootstrap 3
            size: 'normal',
            alignment: 'center',
            itemTexts: function(type, page, current) {
                switch (type) {
                    case "first": return "首頁";
                    case "prev": return "<i class='fa fa-caret-left'></i> 上一頁";
                    case "next": return "下一頁 <i class='fa fa-caret-right'></i>";
                    case "last": return "末頁";
                    case "page": return page;
                }
            },
            tooltipTitles: function(type, page, current) {
                switch (type) {
                    case "first": return "首頁";
                    case "prev": return "上一頁";
                    case "next": return "下一頁";
                    case "last": return "末頁";
                    case "page": return "第 " + page + " 頁";
                }
            },
            pageUrl: function(type, page, current) {
                return "showInfoSearchResult.jsp?pageNoStr=" + page;
            },
            numberOfPages: 6,
            currentPage: <%= pageNo %>,
            totalPages: <%= totalPages %>
        };
        $('#paginator').bootstrapPaginator(options);
    </script>
</body>
</html>

關鍵依賴類

Record 實體類

public class Record {
    private String taizhan_num, tem, hum, pa, rain, win_dir, win_sp;
    private Timestamp date;
    // 標準 getter/setter...
}

DBUtil 連接池工具類 (Tomcat JDBC Pool)

public class DBUtil {
    private static DataSource ds;
    static {
        PoolProperties p = new PoolProperties();
        p.setUrl("jdbc:sqlserver://localhost:1433;DatabaseName=weather");
        p.setDriverClassName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
        p.setUsername("sa");
        p.setPassword("your_password");
        p.setMaxActive(100);
        p.setInitialSize(10);
        p.setMinIdle(10);
        p.setMaxWait(10000);
        p.setValidationQuery("SELECT 1");
        p.setTestOnBorrow(true);
        p.setJdbcInterceptors("ConnectionState;StatementFinalizer");
        ds = new DataSource();
        ds.setPoolProperties(p);
    }
    public static Connection getConnection() throws SQLException { return ds.getConnection(); }
    public static void close(AutoCloseable c) { if (c != null) try { c.close(); } catch (Exception ignored) {} }
}

資料庫分頁寫法對比

資料庫分頁語法範例
SQL ServerROW_NUMBER() 窗口函數SELECT * FROM (SELECT ROW_NUMBER() OVER(ORDER BY id) rn, * FROM t) tmp WHERE rn BETWEEN 21 AND 40
MySQLLIMIT offset, countSELECT * FROM t ORDER BY id LIMIT 20, 20 (跳過 20 條,取 20 條)
Oracle 12c+OFFSET ... FETCHSELECT * FROM t ORDER BY id OFFSET 20 ROWS FETCH NEXT 20 ROWS ONLY
PostgreSQLLIMIT / OFFSETSELECT * FROM t ORDER BY id LIMIT 20 OFFSET 20

分頁通用公式

  • 每頁條數:pageSize
  • 當前頁碼:pageNo (從 1 開始)
  • 起始索引 (1-based):startIndex = (pageNo - 1) * pageSize + 1
  • 結束索引 (1-based):endIndex = pageNo * pageSize
  • 總頁數:totalPages = (totalRecords + pageSize - 1) / pageSize

注意事項

  • Bootstrap 3 必須用 <ul> 容器,bootstrapMajorVersion: 3 配置不可省略
  • Bootstrap 2 使用 <div> 容器,語法不同
  • 官方文檔在解壓包的 document/ 目錄,範例豐富易懂
  • 源碼下載:PaginationExample.rar

此方案適用於傳統 JSP/Servlet 專案,若為前後端分離架構,建議改為 REST API 返回 JSON,前端用 Vue/React + 分頁組件渲染。

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