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

Java MySQL 分頁查詢實戰:LIMIT 子句與 DAO 封裝完整代碼

     編輯:Java 相關知識

MySQL 分頁語法

SELECT * FROM table_name WHERE condition LIMIT offset, pageSize;
-- offset = (pageNumber - 1) * pageSize
-- pageNumber: 第幾頁(從 1 開始)
-- pageSize: 每頁條數

完整 DAO 實現

public class FruitDao {
    private Connection conn;
    private PreparedStatement ps;
    private ResultSet rs;

    public FruitDao() throws Exception {
        conn = DBConnection.getConnection(); // 單例連接池獲取
    }

    // 獲取總頁數
    public int getTotalPages(int pageSize) throws SQLException {
        String sql = "SELECT COUNT(*) FROM fruit";
        try (PreparedStatement ps = conn.prepareStatement(sql);
             ResultSet rs = ps.executeQuery()) {
            if (rs.next()) {
                int totalRows = rs.getInt(1);
                return (int) Math.ceil((double) totalRows / pageSize);
            }
        }
        return 0;
    }

    // 查詢指定頁數據
    public List<Fruit> findByPage(int pageNumber, int pageSize) throws Exception {
        List<Fruit> list = new ArrayList<>();
        String sql = "SELECT * FROM fruit LIMIT ?, ?";
        try (PreparedStatement ps = conn.prepareStatement(sql)) {
            ps.setInt(1, (pageNumber - 1) * pageSize); // offset
            ps.setInt(2, pageSize);                   // pageSize
            try (ResultSet rs = ps.executeQuery()) {
                while (rs.next()) {
                    Fruit f = new Fruit();
                    f.setIds(rs.getString(1));
                    f.setName(rs.getString(2));
                    f.setPrice(rs.getDouble(3));
                    f.setSource(rs.getString(4));
                    f.setNumbers(rs.getInt(5));
                    f.setImage(rs.getString(6));
                    list.add(f);
                }
            }
        }
        return list;
    }

    // 關閉連接(若非連接池管理)
    public void close() throws SQLException {
        if (conn != null) conn.close();
    }
}

關鍵優化點

  1. PreparedStatement 防注入:參數化查詢,自動處理類型轉換。
  2. 連接池管理:生產環境必須使用 HikariCP / Druid,DAO 中不應手動關閉連接(歸還池中)。
  3. 大偏移量性能問題:LIMIT 1000000, 10 需掃描 100 萬行。優化方案:
    • 記住上次最大 ID:WHERE id > lastMaxId LIMIT 10(需 ID 遞增且無刪除)。
    • 延遲關聯:先查主鍵 SELECT id FROM t LIMIT offset, size,再 IN 查詳細字段。
  4. 總數查詢優化:大表 COUNT(*) 慢,可用緩存、近似值或觸發器維護計數表。

Service 層調用示例

public PageResult<Fruit> queryFruits(int pageNum, int pageSize) {
    FruitDao dao = new FruitDao();
    int totalPages = dao.getTotalPages(pageSize);
    List<Fruit> data = dao.findByPage(pageNum, pageSize);
    return new PageResult<>(pageNum, pageSize, totalPages, data);
}

總結

MySQL LIMIT 實現分頁簡單高效,配合 PreparedStatement 與連接池即可滿足中小數據量場景。百萬級以上需採用「游標分頁」或「延遲關聯」優化深分頁性能。

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