<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          用了這么久的PageHelper,你知道原生的分頁查詢原理和步驟嗎

          共 17444字,需瀏覽 35分鐘

           ·

          2021-08-17 02:06

          你知道的越多,不知道的就越多,業(yè)余的像一棵小草!

          成功路上并不擁擠,因為堅持的人不多。

          編輯:業(yè)余草

          juejin.cn/post/6987553953156169742

          推薦:https://www.xttblog.com/?p=5249

          一、分頁查詢概述

          分頁查詢則是在頁面上將本來很多的數(shù)據(jù)分段顯示,每頁顯示用戶自定義的行數(shù)??商岣哂脩趔w驗度,同時減少一次性加載,內存溢出風險。

          1.1、分頁查詢分類

          1.1.1、真分頁

          每次翻頁從數(shù)據(jù)庫中查詢數(shù)據(jù)。

          1. 優(yōu)點:不容易造成內存溢出。
          2. 缺點:實現(xiàn)復雜,性能相對低。

          1.1.2、假分頁

          一次性查詢所有數(shù)據(jù)存入內存,翻頁從內存中獲取數(shù)據(jù)。

          1. 優(yōu)點:實現(xiàn)簡單,性能高。
          2. 缺點:容易造成內存溢出。

          1.2、分頁效果

          發(fā)送請求訪問一個帶有分頁頁面的數(shù)據(jù),會發(fā)現(xiàn)其主要由兩部分組成:

          1. 當前頁的結果集數(shù)據(jù),比如這一頁有哪些商品信息。
          2. 分頁條信息,比如包含【首頁】【上頁】【下頁】【末頁】等。
          分頁效果

          二、分頁的設計

          2.1、分頁需要傳遞的參數(shù)

          2.1.1、用戶需要傳入的參數(shù)

          1. currentPage:當前頁,跳轉到第幾頁,int 類型,設置默認值,比如 1。
          2. pageSize:每頁最多多少條數(shù)據(jù),int 類型,設置默認值,比如 10。

          2.1.2、分頁需要展示的數(shù)據(jù)

          1. start:首頁。
          2. prevPage:上一頁。
          3. nextPage:下一頁。
          4. totalPage:末頁頁碼。
          5. totalCounts:總記錄數(shù)。
          6. currentPage:當前頁。
          7. pageSize:每頁記錄數(shù)。

          2.1.3、分頁需展示的數(shù)據(jù)的來源

          • 來源于用戶傳入:

            1. currentPage:當前頁,int 類型。

            2. pageSize:每頁顯示多少條數(shù)據(jù),int 類型。

          • 來源于兩條 SQL 查詢:

            1. totalCount/rows:數(shù)據(jù)總條數(shù),int 類型。
            2. data/list:每一頁的結果集數(shù)據(jù),List 類型。
          • 來源于程序計算:

            1. totalPage:總頁數(shù)/末頁,int 類型。
            2. prevPage:上一頁,int 類型。
            3. nextPage:下一頁,int 類型。

          2.2、分頁原理

          結果總數(shù)(totalCount/rows)和結果集(data/list)是來源于兩條 SQL:

          1. 第一條SQL:查詢總數(shù),返回一個數(shù)字(總記錄數(shù))。
          select count(*) from province
          1. 查詢符合條件的結果集(返回一個結果集)。
          # 他有兩個參數(shù),一個是起始頁的頁碼,另一個是每頁記錄數(shù)
          # start :(currentPage - 1) * pageSize
          # pageSize:前臺給予
          select * from province limit #{start} ,#{pageSize}
          1. 計算出其余的參數(shù)(總頁數(shù)、上一頁、下一頁)
            // 分頁數(shù)據(jù)通過這個構造器封裝好
            public PageResult(int currentPage, int pageSize, int totalCount, List<T> data) {
              this.currentPage = currentPage;
              this.pageSize = pageSize;
              this.totalCount = totalCount;
              this.data = data;
              // 計算總頁數(shù)(要先算)
              this.totalPage = totalCount % pageSize == 0 ? totalCount / pageSize : totalCount / pageSize + 1;
              // 利用三元運算符來計算上一頁,如果已經(jīng)是第一頁的話,那么他就不會有上一頁,讓他的上一頁為第一頁,否則就當前頁減1為上一頁
              this.prevPage = currentPage - 1 >= 1 ? currentPage - 1 : 1;
              // 利用三元運算符計算下一頁,如果已經(jīng)是最后一頁的話,那么就沒有下一頁了,就不讓他下一頁再增加,否則就當前頁自增
              this.nextPage = currentPage + 1 <= totalPage ? currentPage + 1 : totalPage;

            }

          三、分頁查詢實現(xiàn)

          3.1、訪問流程

          分頁訪問流程

          3.2、分頁參數(shù)的封裝

          為了能在頁面上顯示上述的分頁效果,那么我們就得在把頁面上的每一個數(shù)據(jù)封裝成到某個對象共享給

          JSP。

          如果我們不進行封裝的話,那么這個七個參數(shù)要全部在Session域中去取,比較復雜和惡心。

          我們一般會把多個需要共享的數(shù)據(jù),封裝到一個對象,往后就只需要把數(shù)據(jù)封裝到該對象,再共享該對象即可。

          3.3、編寫PageResult

          package com.qo;

          import java.util.List;
          import lombok.AllArgsConstructor;
          import lombok.Data;
          import lombok.NoArgsConstructor;

          @Data
          @AllArgsConstructor
          @NoArgsConstructor

          /**
            封裝結果數(shù)據(jù)(某一頁的數(shù)據(jù))
           * @author Xiao_Lin
           */

          public class PageResult<T{
            // 用戶輸入的數(shù)據(jù)
            private int currentPage;  // 當前頁碼
            private int pageSize; // 每頁顯示的條數(shù)

            //SQL執(zhí)行后的結果
            private int totalCount; // 總條數(shù)
            private List<T> data; // 當前頁數(shù)據(jù)結果集

            // 利用程序計算出來的
            private int prevPage; // 上一頁
            private int nextPage; // 下一頁
            private int totalPage; // 最后一頁

            // 分頁數(shù)據(jù)通過這個構造器封裝好
            public PageResult(int currentPage, int pageSize, int totalCount, List<T> data) {
              this.currentPage = currentPage;
              this.pageSize = pageSize;
              this.totalCount = totalCount;
              this.data = data;
              // 計算總頁數(shù)(要先算)
              this.totalPage = totalCount % pageSize == 0 ? totalCount / pageSize : totalCount / pageSize + 1;
              // 利用三元運算符來計算上一頁,如果已經(jīng)是第一頁的話,那么他就不會有上一頁,讓他的上一頁為第一頁,否則就當前頁減1為上一頁
              this.prevPage = currentPage - 1 >= 1 ? currentPage - 1 : 1;
              // 利用三元運算符計算下一頁,如果已經(jīng)是最后一頁的話,那么就沒有下一頁了,就不讓他下一頁再增加,否則就當前頁自增
              this.nextPage = currentPage + 1 <= totalPage ? currentPage + 1 : totalPage;
            }
          }

          3.4、修改Mapper(Dao)

           // 查詢總記錄數(shù),傳入一個封裝好的查詢對象,里面的參數(shù)有當前頁、每頁記錄數(shù)(可不傳,盡量傳,為模糊查詢做基礎)
            int queryCount(QueryObject qo);

          // 查詢結果集,傳入一個封裝好的查詢對象,里面封裝好的參數(shù)有當前頁、每頁記錄數(shù)、起始頁頁碼
            List<Province> query(QueryObject qo);

          3.5、修改Service以及ServiceImpl

            PageResult<Province> query(ProvinceQueryObject qo);
          package com.service.impl;

          /**
           * @author 業(yè)余草
           */

          public class ProvinceServiceImpl implements ProvinceService {

            ProvinceMapper mapper = ConnUtils.getConnection().getMapper(ProvinceMapper.class);

            @Override
            public PageResult<Province> query(ProvinceQueryObject qo) {
              // 獲取查詢的記錄數(shù)
              int totalCount = mapper.queryCount(qo);
              // 如果總記錄數(shù)為0,那么說明沒數(shù)據(jù)就不用下一步查詢了,提高效率。
              if (totalCount == 0){
                  // 返回一個查詢結果集,返回當前頁、每頁記錄數(shù)、以及一個空的結果集
                return new PageResult<Province>(qo.getCurrentPage(),qo.getPageSize(),totalCount,Collections.EMPTY_LIST);
              }
                // 記錄數(shù)不為0,查詢出一個結果集
              List<Province> provinces = mapper.query(qo);
                // 返回一個查詢結果集,返回當前頁、每頁記錄數(shù)、以及結果集
              return new PageResult<Province>(qo.getCurrentPage(),qo.getPageSize(),totalCount,provinces);
            }

          3.6、編寫QueryObject

          package com.domain;

          import lombok.AllArgsConstructor;
          import lombok.Data;
          import lombok.NoArgsConstructor;

          /**
           * 封裝分頁查詢需要的兩個請求傳入的分頁參數(shù)
           * @author 業(yè)余草
           */

          @Data
          @AllArgsConstructor
          @NoArgsConstructor
          public class QueryObject {
            private int currentPage = 1// 當前頁碼,要跳轉到哪一頁的頁碼(需要給默認值)
            private int pageSize = 3 ; // 每頁顯示條數(shù)(需要給默認值)
           //用于 Limit 子句第一個 ? 取值,起始頁頁碼
            public int getStart(){
              return (currentPage-1)*pageSize;
            }
          }

          3.7、編寫測試類

           ProvinceService provinceService = new ProvinceServiceImpl();
              QueryObject qo = new QueryObject();
           PageResult<Province> pageResult = provinceService.query(qo);
              System.out.println("當前頁:"+pageResult.getCurrentPage());
              System.out.println("結果集數(shù)據(jù):" + pageResult.getData());
              System.out.println("當前頁總記錄數(shù):" + pageResult.getTotalCount());
              System.out.println("條數(shù):" + pageResult.getData().size());
              System.out.println("總頁數(shù):" + pageResult.getTotalPage());
              System.out.println("上一頁:" + pageResult.getPrePage());
              System.out.println("下一頁:" + pageResult.getNextPage());
          分頁測試結果

          3.7、編寫Servlet

          package com.servlet;

          /**
           * @author 業(yè)余草
           */

          @WebServlet(urlPatterns = "/listall")
          public class ProvinceServlet extends HttpServlet {

            @Override
            protected void service(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException 
          {
              ProvinceService provinceService = new ProvinceServiceImpl();
              // 創(chuàng)建QueryObject對象
              QueryObject qo = new QueryObject();
              // 獲取參數(shù)
              String currentPage = req.getParameter("currentPage");
              // 利用工具類判斷是否傳了這個參數(shù)
              if (StringUtil.hasLength(currentPage)){
                // 如果傳了就賦值
                qo.setCurrentPage(Integer.parseInt(currentPage));
              }
              String pageSize = req.getParameter("pageSize");
              if (StringUtil.hasLength(pageSize)){
                qo.setPageSize(Integer.parseInt(pageSize));
              }
              // 調用業(yè)務層方法來處理請求查詢某一頁數(shù)據(jù)
              PageResult<Province> query = provinceService.query(qo);
              // 把數(shù)據(jù)共享給jsp
              req.setAttribute("pageResult", query);
              // 控制跳轉到 list.jsp 頁面
              req.getRequestDispatcher("/WEB-INF/views/product/list.jsp").forward(req, resp);

            }
          }

          3.7、前臺實現(xiàn)

          包含編寫 Servlet 及 JSP,Servlet 處理請求,調用業(yè)務方法,把查詢到數(shù)據(jù)共享到 JSP 中,展示給用戶。操作步驟:

          1. 瀏覽器發(fā)出分頁請求參數(shù)(去往第幾頁/每頁多少條數(shù)據(jù)),在 Servlet 中接收這些參數(shù),并封裝 到 QueryObject 對象,調用 Service 中分頁查詢方法(query)。
          2. 把得到的分頁查詢結果對象(PageResult)共享在請求作用域中,跳轉到 JSP,顯示即可。
          3. 修改 JSP 頁面,編寫出分頁條信息(分頁條中的信息來源于 PageResult 對象)。
          <%@ page contentType="text/html;charset=UTF-8" language="java" %>
          <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
          <html>
          <head>
              <title>產品列表</title>
              <script type="text/javascript">
                window.onload = function () {
                  var trClzs = document.getElementsByClassName("trClassName");
                  for(var i = 0; i < trClzs.length; i++){
                    trClzs[i].onmouseover = function () {
                      console.log(1);
                      this.style.backgroundColor = "gray";
                    }
                    trClzs[i].onmouseout = function () {
                      console.log(2);
                      this.style.backgroundColor = "";
                    }
                  }
                }
                // 分頁 JS
                function changePageSize() {
                  document.forms[0].submit();
                }
              </script>
          </head>
          <body>

          <form action="/product">
              <table border="1" cellspacing="0" cellpadding="0" width="80%">
                  <tr>
                      <th>編號</th>
                      <th>名稱</th>
                      <th>簡稱</th>
                  </tr>
                  <c:forEach var="province" items="${pageResult.data}"
                             varStatus="status">
                      <tr class="trClassName">
                          <td>${status.count}</td>
                          <td>${province.id}</td>
                          <td>${province.name}</td>
                          <td>${province.abbr}</td>
                          <td>
                              <a href="/listall?cmd=delete&id=${product.id}">刪除</a>
                              <a href="/listall?cmd=input&id=${product.id}">修改</a>
                          </td>
                      </tr>
                  </c:forEach>
                  <tr align="center">
                      <td colspan="9">
                          <a href="/listall?currentPage=1">首頁</a>
                          <a href="/listall?currentPage=${pageResult.prevPage}">上一頁
                          </a>
                          <a href="/listall?currentPage=${pageResult.nextPage}">下一頁
                          </a>
                          <a href="/listall?currentPage=${pageResult.totalPage}">尾頁
                          </a>
                          當前第 ${pageResult.currentPage} / ${pageResult.totalPage} 頁
                          一共 ${pageResult.totalCount} 條數(shù)據(jù)
                          跳轉到<input type="number" onchange="changePageSize()"
                                    name="currentPage" value="${pageResult.currentPage}" style="width: 60px;">頁
                          每頁顯示
                          <select name="pageSize" onchange="changePageSize()">
                              <option value="3" ${pageResult.pageSize == 3 ?
                                      'selected' : ''}> 3 </option>
                              <option value="5" ${pageResult.pageSize == 5 ?
                                      'selected' : ''}> 5 </option>
                              <option value="8" ${pageResult.pageSize == 8 ?
                                      'selected' : ''}> 8 </option>
                          </select>條數(shù)據(jù)
                      </td>
                  </tr>
              </table>
          </form>
          </body>
          </html>
          瀏覽 59
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  秋霞在线一区二区 | 亚洲色图欧美色图偷拍 | 色色色综合色 | 五月天淫秽网站 | 操逼好我看看 |