分頁查詢的入門打開方式(JavaWeb)

技術涵蓋(JavaWeb、HTML、Ajax、JQuery、Bootstrap )

咱們接觸 JavaWeb 這一部分知識的時候,咱們常常會作一些小Demo來練手,不可避免的就須要接觸到必定量的數據,咱們經常須要將數據從數據庫中回顯到頁面中,可是隨着數據量的增長,若是不對數據的查詢或者顯示進行必定的處理,那麼會出現各式各樣的問題,例如:javascript

  • 客戶端:若是數據同時展現在一個頁面中,用戶體驗效果比較差,操做也是極其不方便
  • 服務端:一次請求,查詢到全部的數據,數據傳輸量過大或致使超時或者響應速度變慢,對於服務器的負荷過大

分頁方式

前端 JS 分頁 - 不推薦

咱們能夠請求獲取到全部數據後,使用 JavaScript 來進行數據分頁顯示,單純的在數據的顯示這一方面看確實美觀了不少,而且這種分頁方式要比後端分頁簡單不少css

可是若是存在必定數據量的狀況下,這種方式着實有一些尷尬,他並無解決了咱們服務端的任何問題,反而會讓用戶在等待響應數據耗時過多體驗不佳,不過它仍然是一種分頁方式html

在這裏咱們重點講解後端分頁,因此咱們簡單的演示一下,也把代碼貼出來,因爲咱們 html 中使用的是 BootStrap 前端框架,因此咱們藉助了 bootstrap-table 這個前端分頁插件前端

前端 JS 分頁 演示代碼:java

![11.1-01-003](G:\公衆號\markdown文件\11-分頁與條件查詢\分頁查詢\11.1-01-003.png)<!DOCTYPE html>
<!-- 網頁使用的語言 -->
<html lang="zh-CN">
<head>
  <!-- 指定字符集 -->
  <meta charset="utf-8">
  <!-- 使用Edge最新的瀏覽器的渲染方式 -->
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <!-- viewport視口:網頁能夠根據設置的寬度自動進行適配,在瀏覽器的內部虛擬一個容器,容器的寬度與設備的寬度相同。 width: 默認寬度與設備的寬度相同 initial-scale: 初始的縮放比,爲1:1 -->
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <!-- 上述3個meta標籤*必須*放在最前面,任何其餘內容都*必須*跟隨其後! -->
  <title>用戶信息管理系統</title>

  <!-- 導入CSS的全局樣式 -->
  <link href="css/bootstrap.min.css" rel="stylesheet">
  <!--導入表格插件樣式表-->
  <link href="css/bootstrap-table.min.css" rel="stylesheet">

</head>
<body>
<div class="container">
  <h3 style="text-align: center">用戶信息列表</h3>

  <!--存放工具欄-->
  <div id="toolbar"></div>
  <!--存放生成的表格-->
  <table id="userInfo_table" class="table table-hover">
  </table>

</div>
<!-- jQuery導入,建議使用1.9以上的版本 -->
<script src="js/jquery-2.1.0.min.js"></script>
<!-- 導入bootstrap的js文件 -->
<script src="js/bootstrap.min.js"></script>
<!--導入表格插件-->
<script src="js/bootstrap-table.min.js"></script>
<style type="text/css"> td, th { text-align: center; } </style>

<script> $(function () { $("#userInfo_table").bootstrapTable({ url: 'user/userList', toolbar: '#toolbar', method: 'GET', striped: true, //是否顯示行間隔色 cache: false, //是否使用緩存 toolbarAlign: "right", //工具欄對齊方式 sidePagination: "client", //分頁方式:client客戶端分頁,server服務端分頁 search: true, //是否顯示錶格搜索,此搜索是客戶端搜索,不會進服務端 uniqueId: "id", pageNumber: 1, //初始化加載第一頁 pageSize: 10, //每頁的記錄行數 pageList: [5, 10, 15, 20], //可供選擇的每頁的行數 pagination: true, // 是否分頁 sortable: true, // 是否啓用排序 sortOrder: "asc", //排序方式 showColumns: true, //是否顯示列選擇按鈕 showRefresh: true, //是否顯示刷新按鈕 clickToSelect: true, //是否啓用點擊選中行 // height: 500, //行高 showToggle: true, //是否顯示詳細視圖和列表視圖的切換按鈕 cardView: false, //是否顯示詳細視圖 detailView: false, //是否顯示父子表 queryParamsType: '',//設置請求參數格式 queryParams: function queryParams(params) { //設自定義查詢參數 /*請求遠程數據時,能夠經過修改queryParams來發送其餘參數。 若是queryParamsType = 'limit',params對象包含:limit,offset,search,sort,order。 不然,它包含:pageSize,pageNumber,searchText,sortName,sortOrder。 返回false中止請求。 默認: function(params) { return params }*/ return params; }, columns: [{ title: "全選", field: "select", checkbox: true, width: 20, //寬度 align: "center", //水平 valign: "middle" //垂直 }, { field: 'uid', title: '編號' }, { field: 'username', title: '用戶名' }, { field: 'nickname', title: '暱稱' }, { field: 'email', title: '郵箱' }, { field: 'telephone', title: '電話' }, { field: 'gender', title: '性別' }, { field: 'birthday', title: '生日' },{ field: 'id', title: '操做', // width: 120, align: 'center', valign: 'middle', formatter: actionFormatter }] }) }) //操做欄的格式化 function actionFormatter(value, row, index) { var id = row.id; var result = ""; result += "<button style='cursor: pointer;margin-right: 5px' class='btn btn-primary' title='修改' onclick=''>修改</button>"; result += "<button style='cursor: pointer' class='btn btn-primary' title='刪除' onclick=''>刪除</button>"; return result; } </script>

</body>
</html>

複製代碼

(二) 後端分頁 - 推薦

後端分頁與前端分頁的最大不一樣就是,它不須要一次性向後端請求大量的數據,而是根據用戶的設定,一次請求必定量的數據,而後將這些數據回顯到頁面上,後端分頁也纔是分頁的正確打開方式,其避免了一次性從數據庫獲取不少數據,也能夠美化前端展現效果,優化用戶體驗mysql

後端分頁的實現方式

(一) 總體分析

根據咱們上面所講的,咱們須要的就是前端向後端提交請求後端響應前端須要的數據,而且展現在前端頁面中jquery

前端頁面中,咱們天然須要一個分頁條ajax

咱們根據須要大體改造一下,增長一個首頁和末頁,同時增長一個頁數以及數據記錄統計文字

咱們數據涉及到的問題基本就是上圖以及響應數據在表格中的回顯spring

響應的數據,天然咱們須要 將後端所傳來包含 用戶信息的 list 集合進行遍歷回顯sql

  • 即 須要接收並處理一個 List集合

總記錄數,經後臺在數據庫查詢後給出值

  • 即 須要一個int totalCount 變量 (變量名自行決定)

總頁碼,能夠根據總記錄數以及每頁展現的條數計算出(後面具體講)

  • 即 須要一個 int totalPage 變量

當前頁碼,根據當前頁碼可讓後臺知道你須要的數據是哪些

  • 即 須要一個 int currentPage 變量

每頁展現的條數,這個值能夠暫時寫爲固定的,改進時,能夠交給客戶端選擇,而且提供給後端

  • 即 須要一個 int pageSize 變量

每次查詢的起始位置,每次查詢時經過 LIMIT 語句進行限制,能夠結合每頁顯示的條數得出

  • 即 須要一個 int start 變量

(二) 後端實現

(1) 分頁對象

因爲前端須要接收到後臺傳來的須要數據信息,咱們能夠爲上面咱們簡單分析出所須要的東西,集合成一個分頁對象,方便咱們的數據傳遞

//爲方便後期調用,加上泛型
public class PageBean<T> {
    
    private int totalCount;//總記錄數
    private int totalPage;//總頁數
    private int currentPage;//當前頁碼
    private int pageSize;//每頁顯示的條數
    private List<T> list;//每頁顯示的數據集合

    //省略對應構造,get set方法

}
複製代碼

(2) Servlet 代碼

  • 首先須要獲取到前端傳來的: currentPage、pageSize 兩個 String 類型的值
  • 若是前端不傳遞,默認設置 這兩個變量的值,若傳遞值合理,則將其類型轉爲 int 型(前期能夠先忽略這個,或者在前端設置校驗)
  • 調用 service 查詢 PageBean 分頁對象,並接收其返回值
  • 將PageBean對象序列化爲 json 格式,返回
@WebServlet("/route/*")
public class RouteServlet extends BaseServlet {

    /** * 分頁查詢方法 * * @param request * @param response * @throws ServletException * @throws IOException */
    public void routeQuery(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        String currentPageStr = request.getParameter("currentPage"); //當前頁碼
        String pageSizeStr = request.getParameter("pageSize"); // 每頁顯示的條數

        //當前頁碼,若是不傳遞,默認爲第1頁
        int currentPage = 0;
        if (currentPageStr != null && currentPageStr.length() > 0) {
            currentPage = Integer.parseInt(currentPageStr);
        } else {
            currentPage = 1;
        }

        //每頁顯示條數,若是不傳遞,默認顯示8條記錄
        int pageSize = 0;
        if (pageSizeStr != null && pageSizeStr.length() > 0) {
            pageSize = Integer.parseInt(pageSizeStr);
        } else {
            pageSize = 8;
        }

        //獲取條件查詢參數
        Map<String, String[]> condition = request.getParameterMap();

        //調用service查詢PageBean對象
        RouteService service = new RoutrServiceImpl();
        PageBean<User> userPageBean = service.pageQuery(currentPage, pageSize);

        //將PageBean對象序列化爲json,返回
        ObjectMapper mapper = new ObjectMapper();
        response.setContentType("application/json;charset=utf-8");
        mapper.writeValue(response.getOutputStream(), userPageBean);

    }
}
複製代碼

說明:以上代碼我抽取了Servlet,方便往後擴展方法,剛接觸的朋友 直接建立一個 普通的 Servlet 直接在其中編寫也是同樣能夠的,熟悉的朋友,請忽略我這句話

咱們須要導入 jackson spring mysql druid 的相關jar包

(3) Service 代碼

currentPage 和 pageSize 這兩個值已經肯定了,咱們還須要肯定的有:

總記錄數 totalCount 和 總頁碼數 totalPage 以及須要回顯到前端頁面的 List 集合

  • 總記錄數咱們直接經過dao層查詢就能夠了

  • 總頁碼數咱們能夠經過 (總記錄數 / 每頁顯示的條數) 肯定,要注意不能整除須要多出一頁

  • 查詢 須要在前端頁面展現的數據 list 咱們須要在SQL查詢中 使用 LIMIT進行限制,因此咱們須要提供查詢 的開始點 以及每次 查多少條,這樣才能準確的找到這一頁 應該是哪些數據被回顯到頁面中,簡單的舉舉例就能得每一頁應該從哪裏開始查

    即:int start = (currentPage - 1) * pageSize

public class RouteServiceImpl implements RouteService {

    private RouteDao routeDao = new RouteDaoImpl();

    /** * 分頁查詢 * * @param currentPage * @param pageSize * @param condition * @return */
    @Override
    public PageBean<User> pageQuery(int currentPage, int pageSize, Map<String, String[]> condition) {

        //建立pageBean對象
        PageBean<User> pageBean = new PageBean<User>();
        //設置參數
        pageBean.setCurrentPage(currentPage);
        pageBean.setPageSize(pageSize);
        //調用dao查詢總記錄數
        int totalCount = routeDao.findTotalCount(condition);
        pageBean.setTotalCount(totalCount);
        //調用dao查詢List集合
        int start = (currentPage - 1) * pageSize;
        List<User> list = routeDao.findByPage(start, pageSize, condition);
        pageBean.setList(list);

        //計算總頁碼
        int totalPage = (totalCount % pageSize) == 0 ? totalCount / pageSize : (totalCount / pageSize + 1);
        pageBean.setTotalPage(totalPage);

        return pageBean;
    }
}
複製代碼

(4) Dao 代碼

/** * 根據 start pageSize 查詢當前頁的數據集合 * * @param start * @param pageSize * @return */
@Override
public List<User> findByPage(int start, int pageSize) {

    String sql = "SELECT * FROM user_info LIMIT ? , ?";
     
    return template.query(sql, 
     new BeanPropertyRowMapper<User>(User.class), start, pageSize);
}
複製代碼

(三) 前端實現

文檔載入完畢

$(function () {
    //暫時的傳遞兩個固定值
    var currentPage = 1;
    var pageSize = 8;

    //在這裏調用具體的功能方法
    load(currentPage,pageSize);

});
複製代碼
function load(currentPage, pageSize){
	//具體的回顯代碼,下面詳細解釋這裏些什麼
}
複製代碼

注意:如下代碼均寫在 load方法中

(1) ajax 異步提交

$.get("route/routeQuery", {currentPage:currentPage,pageSize:pageSize}, function (data){
    //傳遞currentPage、pageSize到後端,同時回調函數返回一個data
    //下面是具體代碼
})
複製代碼

咱們下面按照這個流程順序來進行說明

(2) 數據記錄數以及總頁碼數統計

這一步,只要後臺的代碼寫好了,基本不會出現太大的問題的

$("#pageCount").html("共" + data.totalCount + "條記錄,共" + data.totalPage + "頁");
複製代碼

(3) 用戶信息回顯

在HTML 中咱們使用了 代碼拼接的方式實現了這種需求,這個時候返回的 list集合中的一個User的數據被遍歷顯示到咱們的表格中

('#userInfo_table tr:gt(0)').remove();
	var s = '';
	for (var i = 0; i < data.list.length; i++) {
		s += '<tr><td>' + '<input type="checkbox" name="checkItem"/>' + 			'</td><td>' + data.list[i].uid + '</td><td>' + 							data.list[i].username + '</td><td>' + data.list[i].nickname + 			  '</td><td>' + data.list[i].email + '</td><td>' + 							data.list[i].telephone + '</td><td>'+ data.list[i].gender + 			'</td><td>' + data.list[i].birthday + '</td><td>'+ 
            '<button type="submit" class="btn btn-primary" id="updateBtn"> 修改</button>' + '&nbsp' + 
            '<button type="submit" class="btn btn-primary" id="deleteBtn" ">刪除</button>' + '</td>';
            }
			
	$('#userInfo_table').append(s);
複製代碼

這樣咱們的數據回顯就體現出來了,第一頁,正好8個數據 (Ps:前面測試時刪過一些因此編號非0開始)

(4) 首尾頁和翻頁實現

var lis = " ";

//點擊首頁代碼
var firstPage = '<li><a href="javascript:load(1,8)">首頁</a></li>';

//計算上一頁的頁碼
var previousNum = data.currentPage - 1;
if(previousNum <= 0){
    previousNum = 1;
}

//上一頁翻頁的具體代碼
var previousPage = '<li class="threeword"><a href="javascript:load('+previousNum+',8)">&laquo;</a></li>';

lis += firstPage;
lis += previousPage;尾頁以及下一頁和 首頁和上一頁 基本是差很少的
複製代碼

(5) 頁碼的處理

如何處理頁碼比前面幾點就要複雜一點了,咱們既須要用戶點擊後能夠顯示出 正確的用戶信息,其次咱們又須要考慮如何保證只顯示咱們須要的頁碼左右的幾個頁碼,總不能有多少頁就顯示多少個頁碼

咱們仍是須要做出規範,就像這樣:

/* 一共展現8個頁碼,前4後3 若是前面不夠4個,後面補齊8個 若是後面不足8個,前面補齊8個 */

var start;
var end;

//總頁碼超過8頁
if (data.totalPage < 8) {
	start = 1;
    end = data.totalPage;
}else{
	//總頁碼超過8頁
    start = data.currentPage - 4;
    end = data.currentPage + 3;

    //若是前面不夠4個
    if (start < 1) {
    	start  = 1;
        end = start + 7;
	}

	//若是後面不足3個,前面補齊8個
    if (end > data.totalPage ) {
		end = data.totalPage;
		start = end - 7;
    }
}

for (var i = start; i <= end; i++) {
	if (data.currentPage == i){
		var li = '<li class="active"><a href="javascript:load('+i+',8)">'+ i + '</a></li>';
	}else{
        var li = '<li><a href="javascript:load('+i+',8)">' + i + '</a> </li>';
	}
    lis += li;
}
複製代碼

說明:上文使用了這種形式執行href="javascript:load('+i+',8),你們可使用onclick自行優化一下

效果展現

首頁

末頁

總結

這篇文章到這裏就基本結束了,這個樣式是我參考某馬中的一個樣式布的局,使用 HTML + Ajax 替代了 JSP 而後後端的代碼也對應全改寫了 ,不過能夠說是最簡單的一種分頁了,比較適合在JavaWeb階段 剛剛接觸分頁的朋友們瞭解一下,多多少少但願能帶給你們一些幫助,不喜勿噴

一樣,在這裏祝你們新年快樂,也但願你們都能健康平安!

結尾

若是文章中有什麼不足,或者錯誤的地方,歡迎你們留言分享想法,感謝朋友們的支持!

若是能幫到你的話,那就來關注我吧!若是您更喜歡微信文章的閱讀方式,能夠關注個人公衆號

在這裏的咱們素不相識,卻都在爲了本身的夢而努力 ❤

一個堅持推送原創開發技術文章的公衆號:理想二旬不止

相關文章
相關標籤/搜索