IntelliJ IDEA中ajax開發(fā)實(shí)現(xiàn)分頁查詢示例
JavaEE三層架構(gòu)實(shí)現(xiàn)ajax分頁查詢
開發(fā)環(huán)境:
- 系統(tǒng) window10
- IDE:IntelliJ IDEA2017.3.2
- 數(shù)據(jù)庫:MySQL5.5
- 數(shù)據(jù)庫連接工具: Navicat
- 瀏覽器:chrome 版本號(hào) 65.0.3325.181
第一步:代碼實(shí)現(xiàn)之前期準(zhǔn)備
在IDEA中開發(fā)前期配置的工作,網(wǎng)上的帖子很多,我 在這里就不再贅述.主要說三點(diǎn)
在服務(wù)器的配置中,紅色框框的兩項(xiàng)要選擇update classes and resource ,選擇了之后可以實(shí)現(xiàn)熱部署.
要在此處填寫項(xiàng)目的名稱.作為項(xiàng)目的根路徑
導(dǎo)入jar包的方式如圖所示,在dependencie中點(diǎn)擊加號(hào),選中自己創(chuàng)建好的lib文件夾
導(dǎo)入相關(guān)的jar包: c3p0的jar包、DbUtils工具類jar包、fastJson的jar包、mysql驅(qū)動(dòng)jar包
在數(shù)據(jù)庫test03的product表中寫入如下的數(shù)據(jù)
在IDEA中為工程分包,以及導(dǎo)入c3p0連接池的配置

注意,c3p0配置文件,要修改成自己的數(shù)據(jù)庫名稱,以及數(shù)據(jù)庫密碼

在domain包中,創(chuàng)建Product實(shí)體類,根據(jù)數(shù)據(jù)庫中product表的字段,在Product類中,書寫對(duì)應(yīng)的屬性.生成get set方法.
創(chuàng)建獲取連接池對(duì)象的工具類
第二步:無分頁查詢所有的商品信息
實(shí)現(xiàn)思路:
jsp/html----->servlet(web層處理請(qǐng)求與響應(yīng)的數(shù)據(jù)) -----------> service(service層處理邏輯)----------->dao(dao層處理數(shù)據(jù)庫操作)
創(chuàng)建產(chǎn)品頁面,向服務(wù)器發(fā)送請(qǐng)求(獲取所有產(chǎn)品信息)
前端使用了bootstrap響應(yīng)式開發(fā),可以讓頁面更加美觀,開發(fā)更加便捷
頁面信息的代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>商品展示列表</title>
<!--引入bootstrap相關(guān)文件-->
<link rel="stylesheet" href="/ajax_product/bootstrap/css/bootstrap.css" rel="external nofollow" rel="external nofollow" >
<script type="text/javascript" src="/ajax_product/bootstrap/js/jquery-1.11.3.js"></script>
<script type="text/javascript" src="/ajax_product/bootstrap/js/bootstrap.js"></script>
</head>
<script type="text/javascript">
//頁面加載時(shí),向服務(wù)器發(fā)送請(qǐng)求,接收全部的商品數(shù)據(jù)
$(function () {
//===================未分頁,展示所有數(shù)據(jù)===============================
var url ="/ajax_product/product";
//=====向服務(wù)器發(fā)送post請(qǐng)求
$.post(url,function (data) {
//解析服務(wù)器端傳過來的全部數(shù)據(jù)
//============================向表格中展示商品信息
var products = eval(data);
//遍歷數(shù)據(jù)
for (var i = 0; i < products.length; i++) {
//遍歷每一行的數(shù)據(jù)
var protd =$("<tr><td>"+products[i].id+"</td><td>"+products[i].name+"</td><td>"+products[i].count+"</td><td>"+products[i].price+"</td></tr>");
// 并添加到表格中,添加數(shù)據(jù)到表格中
$("#tab").append(protd);
}
},"json")
})
</script>
<body>
<h3 align="center">促銷商品展示</h3>
<div class="container">
<!--商品的表格占一行-->
<div class="row">
<div class="col-md-12">
<!--table-hover表示當(dāng)鼠標(biāo)移入這一行表格的時(shí)候,顏色變化
table-bordered表示給表格加邊框
-->
<table class="table table-hover table-bordered" id="tab">
<tr>
<th>編號(hào)</th>
<th>商品名稱</th>
<th>商品數(shù)量</th>
<th>商品單價(jià)</th>
</tr>
</table>
</div>
</div>
</div>
</body>
</html>
創(chuàng)建一個(gè)servlet來接收請(qǐng)求,獲取所有的產(chǎn)品信息
在IDEA中,創(chuàng)建servlet如下圖所示

在這里不勾選自動(dòng)生成注解

點(diǎn)擊ok之后,IDEA會(huì)自動(dòng)跳轉(zhuǎn)到web.xml文件中,自動(dòng)寫好了Servlet的全路徑名,只需寫url-pattern即可
注意url-pattern需要寫得與ajax請(qǐng)求中的Servlet一致.

web層Servlet的代碼如下:
package com.thc.web;
import com.alibaba.fastjson.JSONObject;
import com.thc.service.ProductService;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
public class Product extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//處理響應(yīng)與請(qǐng)求的亂碼
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//由于是顯示所有的產(chǎn)品信息,沒有參數(shù)接收
//需要調(diào)用服務(wù)層查找所有數(shù)據(jù)的方法,獲取結(jié)果,響應(yīng)給客戶端
ProductService service = new ProductService();
try {
//調(diào)用業(yè)務(wù)層的方法,獲取所有的商品
List<com.thc.domain.Product> allProuct = service.findAllProuct();
//把得到的數(shù)據(jù),轉(zhuǎn)為json類型的數(shù)據(jù)
String jsonString = JSONObject.toJSONString(allProuct);
//回寫給瀏覽器
response.getWriter().write(jsonString);
} catch (SQLException e) {
e.printStackTrace();
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
}
在service層,從dao層獲取數(shù)據(jù),返回給web層的Servlet
web層調(diào)用service層的代碼如下
package com.thc.service;
import com.thc.dao.ProductDao;
import com.thc.domain.Product;
import java.sql.SQLException;
import java.util.List;
public class ProductService {
//在service層,從dao層獲取數(shù)據(jù),返回?cái)?shù)據(jù)給web層
public List<Product> findAllProuct() throws SQLException {
ProductDao dao = new ProductDao();
//調(diào)用dao層查詢所有的商品
List<Product> allProduct = dao.findAllProduct();
return allProduct;
}
}
在dao層從服務(wù)器中查詢數(shù)據(jù),給service層
package com.thc.dao;
import com.thc.domain.Product;
import com.thc.utils.JdbcUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import java.sql.SQLException;
import java.util.List;
//=================dao層專門負(fù)責(zé)數(shù)據(jù)庫操作
public class ProductDao {
//===========查詢所有商品信息
public List<Product> findAllProduct() throws SQLException {
//利用dbutils,創(chuàng)建QueryRunner核心對(duì)象
QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());
//書寫sql語句,查詢所有的商品
String sql = "select * from product";
//把商品到的商品,轉(zhuǎn)為list集合,泛型為product
List<Product> products = qr.query(sql, new BeanListHandler<>(Product.class));
return products;
}
}
dao層拿到數(shù)據(jù)后,傳遞給service層,service層再傳遞給web層的servlet,servlet拿到數(shù)據(jù)后,是保存在list集合中的,再把list集合轉(zhuǎn)為json數(shù)據(jù)類型,寫給瀏覽器.前端頁面中的如下代碼,就是在解析servlet返回的json數(shù)據(jù)
$.post(url,function (data) {
//解析服務(wù)器端傳過來的全部數(shù)據(jù)
//============================向表格中展示商品信息
var products = eval(data);
//遍歷數(shù)據(jù)
for (var i = 0; i < products.length; i++) {
//遍歷每一行的數(shù)據(jù)
var protd =$("<tr><td>"+products[i].id+"</td><td>"+products[i].name+"</td><td>"+products[i].count+"</td><td>"+products[i].price+"</td></tr>");
// 并添加到表格中,添加數(shù)據(jù)到表格中
$("#tab").append(protd);
}
},"json")
通過谷歌瀏覽器自帶的抓包工具,可以看到servlet響應(yīng)的數(shù)據(jù)

把響應(yīng)的數(shù)據(jù)全部復(fù)制下來,就是如下的數(shù)據(jù).一個(gè)數(shù)組中嵌套了產(chǎn)品的對(duì)象.
對(duì)象中都是以鍵值對(duì)的形式存在的.
例如第一個(gè)數(shù)據(jù)中,鍵為count,值為100. 鍵為id,值為1,鍵為name,值為電視機(jī),鍵為price 值為2000
[
{"count":100,"id":1,"name":"電視機(jī)","price":2000},
{"count":200,"id":2,"name":"洗衣機(jī)","price":1000},
{"count":300,"id":3,"name":"空調(diào)","price":3000},
{"count":50,"id":4,"name":"投影儀","price":2000},
{"count":1000,"id":5,"name":"HP電腦","price":4000},
{"count":100,"id":6,"name":"蘋果手機(jī)","price":5000},
{"count":60,"id":7,"name":"縫紉機(jī)","price":2000},
{"count":100,"id":8,"name":"小米盒子","price":2200},
{"count":300,"id":9,"name":"飲水機(jī)","price":2000},
{"count":200,"id":10,"name":"凈水器","price":2000},
{"count":500,"id":11,"name":"電暖器","price":2000},
{"count":100,"id":12,"name":"榨汁機(jī)","price":399},
{"count":200,"id":13,"name":"電壓力鍋","price":498},
{"count":300,"id":14,"name":"電飯煲","price":299},
{"count":50,"id":15,"name":"微波爐","price":1299},
{"count":200,"id":16,"name":"豆?jié){機(jī)","price":199},
{"count":300,"id":17,"name":"電磁爐","price":398},
{"count":500,"id":18,"name":"加濕器","price":99},
{"count":250,"id":19,"name":"剃須刀","price":98},
{"count":1000,"id":20,"name":"舒膚佳","price":16.5},
{"count":1200,"id":21,"name":"雕牌","price":8.8},
{"count":1500,"id":22,"name":"立白","price":9.9}
]
不分頁的情況下,展示的效果如下:
一個(gè)頁面中,把所有的數(shù)據(jù)都展示出來了,如果數(shù)據(jù)非常多,例如上百度搜索一個(gè)關(guān)鍵詞,結(jié)果可能有上萬上億條,一次性從數(shù)據(jù)庫中,拿這么多的結(jié)果給瀏覽器,是很長(zhǎng)的時(shí)間的,用戶體驗(yàn)極差,因此需要分頁技術(shù).采用物理分頁,
一次只從數(shù)據(jù)庫中查詢當(dāng)前頁面需要的信息.
第三步:傳遞當(dāng)前頁面數(shù)和每頁顯示的數(shù)量給服務(wù)器
html頁面中需要增加當(dāng)前頁面數(shù)和每頁顯示的數(shù)量這兩個(gè)變量,傳遞給服務(wù)器
更改代碼的如下圖所示:

在servlet層需要接收參數(shù),并且從service層查詢對(duì)應(yīng)的當(dāng)前頁的數(shù)據(jù),代碼如下:
public class Product extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//處理響應(yīng)與請(qǐng)求的亂碼
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//當(dāng)前頁面
int pageNo = Integer.parseInt(request.getParameter("pageNo"));
//每頁的顯示條數(shù)
int pageSize = Integer.parseInt(request.getParameter("pageSize"));
//由于是顯示所有的產(chǎn)品信息,沒有參數(shù)接收
//需要調(diào)用服務(wù)層查找所有數(shù)據(jù)的方法,獲取結(jié)果,響應(yīng)給客戶端
ProductService service = new ProductService();
try {
//根據(jù)當(dāng)前頁和每頁顯示的數(shù)目,來從service層,獲取數(shù)據(jù)
List<com.thc.domain.Product> product = service.findProduct(pageNo, pageSize);
String jsonString = JSONObject.toJSONString(product);
//回寫給瀏覽器
response.getWriter().write(jsonString);
} catch (SQLException e) {
e.printStackTrace();
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
}
service層新增的查找當(dāng)前頁面數(shù)據(jù)方法
public List<Product> findProduct(int pageNo, int pageSize) throws SQLException {
ProductDao dao = new ProductDao();
List<Product> product = dao.findProduct(pageNo, pageSize);
return product;
}
dao層新增的從數(shù)據(jù)庫查找當(dāng)前頁面的方法
public List<Product> findProduct(int pageNo, int pageSize) throws SQLException {
QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());
String sql ="select * from product limit ?,?";
//limit第一個(gè)參數(shù):從數(shù)據(jù)庫中的哪里開始查,索引是從0開始的
//第二個(gè)參數(shù):每次查多少個(gè)
//第一個(gè)參數(shù)的規(guī)律是:當(dāng)前頁數(shù)減一,乘以每頁查詢的個(gè)數(shù)
List<Product> productList = qr.query(sql, new BeanListHandler<>(Product.class), (pageNo - 1) * pageSize, pageSize);
return productList;
}
瀏覽器端顯示如下圖所示:每次只會(huì)顯示pageSize(當(dāng)前的值為6)個(gè)數(shù)的商品信息.
但是還不能動(dòng)態(tài)的通過點(diǎn)擊頁面按鈕來實(shí)現(xiàn)翻頁.

那么就要考慮頁面如何顯示分頁條以及數(shù)據(jù)該如何封裝?
我們知道頁面的分頁條 顯示 的頁數(shù)是動(dòng)態(tài)變化的 ,總頁數(shù) =數(shù)據(jù)的總條數(shù)/每頁顯示的數(shù)據(jù),要向上取整。也就是說,我們的頁面除了需要List<Product>數(shù)據(jù)之外,還需要數(shù)據(jù)的總條數(shù)、總頁數(shù)、當(dāng)前頁、每頁顯示數(shù)量。另外當(dāng)前頁pageNo也是動(dòng)態(tài)變化的,在頁面上點(diǎn)擊多少頁,pageNo就是幾。所以, 我們需要再創(chuàng)建一個(gè)javabean(PageBean.java)來封裝這些數(shù)據(jù) ,在服務(wù)端得到這些數(shù)據(jù)之后轉(zhuǎn)成json數(shù)據(jù)發(fā)送給客戶端顯示。
第四步:將頁面的相關(guān)數(shù)據(jù)封裝為一個(gè)JavaBean
在domain包內(nèi)創(chuàng)建一個(gè)類,名為PageBean,屬性如下:
private int pageNo;//當(dāng)前頁數(shù) private int pageSize;//每頁顯示的數(shù)量 private int totalCount;//一共有多少個(gè)商品信息數(shù)據(jù) private int totalPage;//一共有多少頁數(shù)據(jù) private List<Product> products;//商品信息數(shù)據(jù)的集合
在web層傳遞service層當(dāng)前頁面數(shù)(pageNo),和每頁顯示的條數(shù)(pageSize),返回給web層一個(gè)PageBean
web層的最終代碼如下
public class Product extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//處理響應(yīng)與請(qǐng)求的亂碼
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//當(dāng)前頁面
int pageNo = Integer.parseInt(request.getParameter("pageNo"));
//每頁的顯示條數(shù)
int pageSize = Integer.parseInt(request.getParameter("pageSize"));
//由于是顯示所有的產(chǎn)品信息,沒有參數(shù)接收
//需要調(diào)用服務(wù)層查找所有數(shù)據(jù)的方法,獲取結(jié)果,響應(yīng)給客戶端
ProductService service = new ProductService();
try {
/* 調(diào)用業(yè)務(wù)層的方法,獲取所有的商品
List<com.thc.domain.Product> allProuct = service.findAllProuct();
把得到的數(shù)據(jù),轉(zhuǎn)為json類型的數(shù)據(jù)
String jsonString = JSONObject.toJSONString(allProuct);*/
//根據(jù)當(dāng)前頁和每頁顯示的數(shù)目,來從service層,獲取數(shù)據(jù)
//List<com.thc.domain.Product> product = service.findProduct(pageNo, pageSize);
//===============從web層拿到pagebean的數(shù)據(jù)=================================
PageBean pageBean = service.findPageInfo(pageNo, pageSize);
//===============把數(shù)據(jù)轉(zhuǎn)為json===============================
String jsonString = JSONObject.toJSONString(pageBean);
//================回寫給瀏覽器====================
response.getWriter().write(jsonString);
} catch (SQLException e) {
e.printStackTrace();
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
}
在service需要獲取pageBean的全部信息,pageNo和pageSize是已知的.需要從dao層獲取商品的信息數(shù)據(jù),LIst集合,還需要獲取總的商品信息數(shù)據(jù)totalCount.總共有多少頁可以通過總數(shù)據(jù)除以每頁顯示的數(shù)據(jù),并向上取整.
service層的最終代碼如下:
public class ProductService {
//在service層,從dao層獲取數(shù)據(jù),返回?cái)?shù)據(jù)給web層
//=========Service層處理所有商品信息的數(shù)據(jù)給web層====================
public List<Product> findAllProuct() throws SQLException {
ProductDao dao = new ProductDao();
//調(diào)用dao層查詢所有的商品
List<Product> allProduct = dao.findAllProduct();
return allProduct;
}
//============service層查詢某個(gè)特定頁面的數(shù)據(jù)給web層=================================
public List<Product> findProduct(int pageNo, int pageSize) throws SQLException {
ProductDao dao = new ProductDao();
List<Product> product = dao.findProduct(pageNo, pageSize);
return product;
}
//============service層封裝pagebean數(shù)據(jù)===================================
public PageBean findPageInfo(int pageNo, int pageSize) throws SQLException {
ProductDao dao = new ProductDao();
List<Product> product = dao.findProduct(pageNo, pageSize);
int totalCount = dao.findTotalCount();
PageBean pb = new PageBean();
//封裝數(shù)據(jù)
pb.setTotalCount(totalCount);
pb.setPageNo(pageNo);
pb.setPageSize(pageSize);
pb.setProducts(product);
//向上取整,計(jì)算總頁數(shù),不要忘了乘以1.0,否則會(huì)少一頁數(shù)據(jù)
int totalPage = (int) Math.ceil(totalCount*1.0/pageSize);
pb.setTotalPage(totalPage);
//把數(shù)據(jù)給servlet
return pb;
}
}
在dao層,新增了一個(gè)方法,用于查詢數(shù)據(jù)庫總信息的總個(gè)數(shù)
dao層最終的代碼如下
//=================dao層專門負(fù)責(zé)數(shù)據(jù)庫操作
public class ProductDao {
//===========查詢所有商品信息
public List<Product> findAllProduct() throws SQLException {
//利用dbutils,創(chuàng)建QueryRunner核心對(duì)象
QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());
//書寫sql語句,查詢所有的商品
String sql = "select * from product";
//把商品到的商品,轉(zhuǎn)為list集合,泛型為product
List<Product> products = qr.query(sql, new BeanListHandler<>(Product.class));
return products;
}
//=======================查詢當(dāng)前頁的產(chǎn)品信息=====================
public List<Product> findProduct(int pageNo, int pageSize) throws SQLException {
QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());
String sql ="select * from product limit ?,?";
//limit第一個(gè)參數(shù):從數(shù)據(jù)庫中的哪里開始查,索引是從0開始的
//第二個(gè)參數(shù):每次查多少個(gè)
//第一個(gè)參數(shù)的規(guī)律是:當(dāng)前頁數(shù)減一,乘以每頁查詢的個(gè)數(shù)
List<Product> productList = qr.query(sql, new BeanListHandler<>(Product.class), (pageNo - 1) * pageSize, pageSize);
return productList;
}
//===============查詢總共有多少條數(shù)據(jù)=================
public int findTotalCount() throws SQLException {
QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());
String sql = "select count(*) from product";
Long countL =(Long) qr.query(sql, new ScalarHandler());
return countL.intValue();
}
}
第五步:處理前端頁面
在table標(biāo)簽的下面,增加一行,提供分頁的組件.并把li代碼注釋掉,因?yàn)樾枰獎(jiǎng)討B(tài)展示.

先聲明需要接收的參數(shù)變量
var url ="/ajax_product/product"; var pageNo=1;//當(dāng)前頁面設(shè)置為1 var pageSize=6;//每頁顯示6條商品信息 var totalPage;//一共有多少頁數(shù)據(jù) var products;//商品的數(shù)據(jù)信息
寫好了ajax的post請(qǐng)求之后,抓包測(cè)試瀏覽器是否接收到數(shù)據(jù)
$.post(
url,//給服務(wù)器傳送數(shù)據(jù)的地址
{"pageNo": pageNo, "pageSize": pageSize},//給瀏覽器傳遞當(dāng)前頁面數(shù)和每頁顯示的條數(shù)
function (data) {})
在抓包拿到了如下 的數(shù)據(jù)
{"pageNo":1,
"pageSize":6,
"products":[{"count":100,"id":1,"name":"電視機(jī)","price":2000},
{"count":200,"id":2,"name":"洗衣機(jī)","price":1000},
{"count":300,"id":3,"name":"空調(diào)","price":3000},
{"count":50,"id":4,"name":"投影儀","price":2000},
{"count":1000,"id":5,"name":"HP電腦","price":4000},
{"count":100,"id":6,"name":"蘋果手機(jī)","price":5000}],
"totalCount":22,
"totalPage":3}
說明服務(wù)器端能夠正常給瀏覽器響應(yīng)數(shù)據(jù).再接著寫前端代碼
顯示表格中的數(shù)據(jù)
先將后端得到的數(shù)據(jù)解析,再同步到j(luò)s代碼中,通過pagebean.products獲得所有product對(duì)象的數(shù)據(jù)的數(shù)組,再遍歷這個(gè)數(shù)組,把product屬性的值拼接到表格中去.
代碼如下
$.post(
url,//給服務(wù)器傳送數(shù)據(jù)的地址
{"pageNo": pageNo, "pageSize": pageSize},//給瀏覽器傳遞當(dāng)前頁面數(shù)和每頁顯示的條數(shù)
function (data) {
//解析服務(wù)器端傳過來的全部pagebean數(shù)據(jù),格式為json類型
var pagebean = eval(data);
//同步數(shù)據(jù)
pageNo=pagebean.pageNo;
pageSize=pagebean.pageSize;
totalPage=pagebean.totalPage;
products=pagebean.products;
//顯示表格中的數(shù)據(jù)===============================================
for (var i = 0; i < products.length; i++) {
//遍歷每一行的數(shù)據(jù)
var protd =$("<tr><td>"+products[i].id+"</td><td>"+products[i].name+"</td> <td>"+products[i].count+"</td><td>"+products[i].price+"</td> </tr>");
// 并添加到表格中,添加數(shù)據(jù)到表格中
$("#tab").append(protd);
}
},"json")
這段代碼寫完后,可開啟服務(wù)器,測(cè)試能否獲取數(shù)據(jù)到表格中.經(jīng)測(cè)試成功顯示數(shù)據(jù).
顯示分頁條的數(shù)據(jù)
先顯示上一頁與下一頁的數(shù)據(jù)
//顯示分頁條的數(shù)據(jù)
//先不考慮功能,先能顯示出來
//顯示上一頁
var preLi=$('<li class="disabled"><a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >上一頁</a></li>');
//通過類選擇器,添加進(jìn)去
$(".pager").append(preLi);
//顯示下一頁
var nextLi=$('<li class="disabled"><a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >下一頁</a></li>');
//通過類選擇器,添加進(jìn)去
$(".pager").append(nextLi);
進(jìn)測(cè)試效果如下:
顯示頁碼數(shù)據(jù):
//顯示分頁條的數(shù)據(jù)
//先不考慮功能,先能顯示出來
//顯示上一頁
var preLi=$('<li class="disabled"><a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >上一頁</a></li>');
//通過類選擇器,添加進(jìn)去
$(".pager").append(preLi);
//遍歷顯示頁碼
for (var i = 1; i <= totalPage; i++) {
//創(chuàng)建li標(biāo)簽
var li=$('<li><a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >'+i+'</a></li>');
//通過類選擇器,添加到ul中
$(".pager").append(li);
}
//顯示下一頁
var nextLi=$('<li class="disabled"><a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >下一頁</a></li>');
//通過類選擇器,添加進(jìn)去
$(".pager").append(nextLi);
效果如下圖所示:
當(dāng)前頁高亮顯示
由于bootstrap中,pager類不支持高亮顯示,因此把分頁的類換為pagination.
高亮的邏輯是,在遍歷的是否,判斷是否為當(dāng)前頁(pageNo).
給li標(biāo)簽添加class的active 屬性
//遍歷顯示頁碼
for (var i = 1; i <= totalPage; i++) {
var li;
if(i===pageNo){
//=========是當(dāng)前頁,就高亮顯示
li=$('<li class="active"><a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >'+i+'</a></li>');
//通過類選擇器,添加到ul中
$(".pagination").append(li);
}else{
//========不是當(dāng)前頁,不高亮顯示
li=$('<li><a href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >'+i+'</a></li>');
//通過類選擇器,添加到ul中
$(".pagination").append(li);
}
}
效果如下

給頁碼添加點(diǎn)擊事件,切換數(shù)據(jù).
當(dāng)前頁不需要添加點(diǎn)擊事件

給頁數(shù)里面的a標(biāo)簽添加onclick事件,綁定一個(gè)skipPage()函數(shù),skipPage()函數(shù)里面所做的操作實(shí)際上就是我們獲取第1頁數(shù)據(jù)的向服務(wù)器發(fā)送Ajax的post請(qǐng)求的操作,所以 把$(function(){})的代碼復(fù)制到skipPage()函數(shù)中 ,然后在頁面加載完成時(shí)調(diào)用skipPage()函數(shù),傳入1就表示默認(rèn)加載第1頁數(shù)據(jù)。此時(shí),$(function(){})只會(huì)執(zhí)行一次.而skipPage()成了遞歸函數(shù),自己調(diào)用自己.但一次點(diǎn)擊事件,只會(huì)調(diào)用一次skipPage方法,與java中的遞歸不太一樣.

執(zhí)行完此段代碼后,點(diǎn)擊不同的代碼,發(fā)現(xiàn)表格的內(nèi)容以及分頁條會(huì)不斷疊加
如下圖所示:
每次加載數(shù)據(jù)時(shí),清空數(shù)據(jù). 清空分頁條

添加了清空分頁條的代碼后,發(fā)現(xiàn),分頁條沒有疊加了,但是表格還在疊加
清空表格
$("#tab").empty(); 給表格執(zhí)行清空代碼后發(fā)現(xiàn)如下現(xiàn)象:

表格的第一行標(biāo)題沒有了,所以需要用選擇器,把第一行排除在外.

$("#tab tr:not(:first)")的含義是
先根據(jù)id選擇器,選擇表格
再由層級(jí)選擇器,選擇tr行
再由基本選擇器not中嵌套基本選擇器first,代表不是第一行
整體的意思是,選擇了表格了不是第一行的元素,調(diào)用empty()方法,刪除匹配的元素集合中所有的子節(jié)點(diǎn)。
測(cè)試后,能夠不刪除第一行數(shù)據(jù)
上一頁判斷是否可用,以及切換頁碼功能
如果當(dāng)前頁是第一頁,上一頁功能就不可用.
如果當(dāng)前頁不是第一頁,就添加點(diǎn)擊事件,切換到上一頁,把頁碼減一.
//顯示上一頁,判斷是否可用
var preLi;
if(pageNo===1){
//如果當(dāng)前頁是第一頁,上一頁功能就不可用
preLi=$('<li class="disabled"><a href="javascript:void(0)" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >上一頁</a></li>');
}else{
preLi=$('<li><a href="javascript:void(0)" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" onclick="skipPage('+(pageNo-1)+')">上一頁</a></li>');
}
//通過類選擇器,添加進(jìn)去
$(".pagination").append(preLi);
下一頁判斷是否可用,以及切換頁碼功能
如果當(dāng)前頁是最后一頁,上一頁功能就不可用.
如果當(dāng)前頁不是最后一頁,就添加點(diǎn)擊事件,切換到下一頁,把頁碼加一.
//顯示下一頁,判斷是否可用
var nextLi;
if(pageNo===totalPage){
//如果當(dāng)前頁是最后一頁,上一頁功能就不可用.
nextLi=$('<li class="disabled"><a href="javascript:void(0)" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >下一頁</a></li>');
}else {
//如果當(dāng)前頁不是最后一頁,就添加點(diǎn)擊事件,切換到上一頁,把頁碼減一.
nextLi=$('<li><a href="javascript:void(0)" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" onclick="skipPage('+(pageNo+1)+')">下一頁</a></li>');
}
//通過類選擇器,添加進(jìn)去
$(".pagination").append(nextLi);
至此,前端頁面的代碼全部完成,功能全部實(shí)現(xiàn)
前端頁面的全部代碼如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>商品展示列表</title>
<!--引入bootstrap相關(guān)文件-->
<link rel="stylesheet" href="/ajax_product/bootstrap/css/bootstrap.css" rel="external nofollow" rel="external nofollow" >
<script type="text/javascript" src="/ajax_product/bootstrap/js/jquery-1.11.3.js"></script>
<script type="text/javascript" src="/ajax_product/bootstrap/js/bootstrap.js"></script>
</head>
<script type="text/javascript">
var url ="/ajax_product/product";
var pageNo=1;//當(dāng)前頁面設(shè)置為1
var pageSize=5;//每頁顯示6條商品信息
var totalPage;//一共有多少頁數(shù)據(jù)
var products;//商品的數(shù)據(jù)信息
//頁面加載時(shí),向服務(wù)器發(fā)送請(qǐng)求,接收全部的商品數(shù)據(jù)
$(function () {
skipPage(1);
});
function skipPage(page) {
//===========分頁時(shí)的post請(qǐng)求===================================
pageNo=page;
//=====向服務(wù)器發(fā)送post請(qǐng)求
$.post(
url,//給服務(wù)器傳送數(shù)據(jù)的地址
{"pageNo": pageNo, "pageSize": pageSize},//給瀏覽器傳遞當(dāng)前頁面數(shù)和每頁顯示的條數(shù)
function (data) {
//解析服務(wù)器端傳過來的全部pagebean數(shù)據(jù),格式為json類型
var pagebean = eval(data);
//同步數(shù)據(jù)
pageNo=pagebean.pageNo;
pageSize=pagebean.pageSize;
totalPage=pagebean.totalPage;
products=pagebean.products;
//顯示表格中的數(shù)據(jù)===============================================
//$("#tab").empty();
$("#tab tr:not(:first)").empty();
for (var i = 0; i < products.length; i++) {
//遍歷每一行的數(shù)據(jù)
var protd =$("<tr><td>"+products[i].id+"</td><td>"+products[i].name+" </td><td>"+products[i].count+"</td><td>"+products[i].price+"</td></tr>");
// 并添加到表格中,添加數(shù)據(jù)到表格中
$("#tab").append(protd);
}
//顯示分頁條的數(shù)據(jù)========================================================
//清空分頁條
$(".pagination").empty();
//先不考慮功能,先能顯示出來
//顯示上一頁,判斷是否可用
var preLi;
if(pageNo===1){
//如果當(dāng)前頁是第一頁,上一頁功能就不可用.
preLi=$('<li class="disabled"><a href="javascript:void(0)" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >上一頁</a> </li>');
}else{
//如果當(dāng)前頁不是第一頁,就添加點(diǎn)擊事件,切換到上一頁,把頁碼減一.
preLi=$('<li><a href="javascript:void(0)" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" onclick="skipPage('+(pageNo- 1)+')">上一頁</a></li>');
}
//通過類選擇器,添加進(jìn)去
$(".pagination").append(preLi);
//遍歷顯示頁碼
for (var i = 1; i <= totalPage; i++) {
var li;
if(i===pageNo){
//=========是當(dāng)前頁,就高亮顯示
li=$('<li class="active"><a href="javascript:void(0)" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >'+i+'</a> </li>');
//通過類選擇器,添加到ul中
$(".pagination").append(li);
}else{
//========不是當(dāng)前頁,不高亮顯示.添加點(diǎn)擊事件,參數(shù)傳遞為當(dāng)前頁碼
li=$('<li><a href="javascript:void(0)" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" onclick="skipPage('+i+')">'+i+'</a></li>');
//通過類選擇器,添加到ul中
$(".pagination").append(li);
}
}
//顯示下一頁,判斷是否可用
var nextLi;
if(pageNo===totalPage){
//如果當(dāng)前頁是最后一頁,上一頁功能就不可用.
nextLi=$('<li class="disabled"><a href="javascript:void(0)" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >下一頁</a> </li>');
}else {
//如果當(dāng)前頁不是最后一頁,就添加點(diǎn)擊事件,切換到上一頁,把頁碼減一.
nextLi=$('<li><a href="javascript:void(0)" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" onclick="skipPage('+ (pageNo+1)+')">下一頁</a></li>');
}
//通過類選擇器,添加進(jìn)去
$(".pagination").append(nextLi);
},"json")
}
</script>
<body>
<h3 align="center">促銷商品展示</h3>
<div class="container">
<!--商品的表格占一行-->
<div class="row">
<div class="col-md-12">
<!--table-hover表示當(dāng)鼠標(biāo)移入這一行表格的時(shí)候,顏色變化
table-bordered表示給表格加邊框
-->
<table class="table table-hover table-bordered" id="tab">
<tr>
<th>編號(hào)</th>
<th>商品名稱</th>
<th>商品數(shù)量</th>
<th>商品單價(jià)</th>
</tr>
</table>
</div>
</div>
<div class="row">
<div class="col-md-4 col-md-offset-4" >
<nav>
<ul class="pagination">
<!--此處代碼由js動(dòng)態(tài)生成
-->
</ul>
</nav>
</div>
</div>
</div>
</body>
</html>
總結(jié)
此分頁功能,用到了JavaEE的三層架構(gòu)的思想.每一層各司其職,做各自的負(fù)責(zé)的事情.前端部分為難點(diǎn).需要處理的細(xì)節(jié)很多.前端涉及到了ajax和jquery.jQuery的一些語法與選擇器的相關(guān)的東西要非常熟練.還用到了bootrap響應(yīng)式開發(fā),讓前端頁面的布局更加方便.
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Spring Boot學(xué)習(xí)入門之統(tǒng)一異常處理詳解
我們?cè)谧鯳eb應(yīng)用的時(shí)候,請(qǐng)求處理過程中發(fā)生錯(cuò)誤是非常常見的情況。下面這篇文章主要給大家介紹了關(guān)于Spring Boot學(xué)習(xí)入門之統(tǒng)一異常處理的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下。2017-09-09
java實(shí)現(xiàn)Socket通信之單線程服務(wù)
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)Socket通信的單線程服務(wù),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07
Java 多態(tài)中繼承的轉(zhuǎn)型詳解與用法分析
繼承是java面向?qū)ο缶幊碳夹g(shù)的一塊基石,因?yàn)樗试S創(chuàng)建分等級(jí)層次的類。繼承就是子類繼承父類的特征和行為,使得子類對(duì)象(實(shí)例)具有父類的實(shí)例域和方法,或子類從父類繼承方法,使得子類具有父類相同的行為2021-10-10
Spring中的模塊與應(yīng)用場(chǎng)景詳解
這篇文章主要介紹了Spring中的模塊與應(yīng)用場(chǎng)景詳解,Spring 框架可以為 Java 應(yīng)用程序開發(fā)提供全面的基礎(chǔ)設(shè)施支持,它是現(xiàn)在非常流行的 Java 開源框架,對(duì)于一個(gè) Java 開發(fā)人員來說,熟練掌握 Spring 是必不可少的,需要的朋友可以參考下2023-09-09
淺談Java HttpURLConnection請(qǐng)求方式
這篇文章主要介紹了淺談Java HttpURLConnection請(qǐng)求方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-08-08
Spring?Boot使用Schedule實(shí)現(xiàn)定時(shí)任務(wù)的方法
這篇文章主要介紹了Spring?Boot使用Schedule實(shí)現(xiàn)定時(shí)任務(wù),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-03-03

