IntelliJ IDEA中ajax开发实现分页查询示例

网友投稿 390 2023-02-11


IntelliJ IDEA中ajax开发实现分页查询示例

javaEE三层架构实现ajax分页查询

开发环境:

系统 window10

IDE:IntelliJ IDEA2017.3.2

数据库:mysql5.5

数据库连接工具: Navicat

浏览器:chrome 版本号 65.0.3325.181

第一步:代码实现之前期准备

在IDEA中开发前期配置的工作,网上的帖子很多,我 在这里就不再赘述.主要说三点

在服务器的配置中,红色框框的两项要选择update classes and resource ,选择了之后可以实现热部署.

要在此处填写项目的名称.作为项目的根路径

导入jar包的方式如图所示,在dependencie中点击加号,选中自己创建好的lib文件夹

导入相关的jar包: c3p0的jar包、DbUtils工具类jar包、fastjson的jar包、mysql驱动jar包

在数据库test03的product表中写入如下的数据

在IDEA中为工程分包,以及导入c3p0连接池的配置

注意,c3p0配置文件,要修改成自己的数据库名称,以及数据库密码

在domain包中,创建Product实体类,根据数据库中product表的字段,在Product类中,书写对应的属性.生成get set方法.

创建获取连接池对象的工具类

第二步:无分页查询所有的商品信息

实现思路:

jsp/html----->servlet(web层处理请求与响应的数据) -----------> service(service层处理逻辑)----------->dao(dao层处理数据库操作)

创建产品页面,向服务器发送请求(获取所有产品信息)

前端使用了bootstrap响应式开发,可以让页面更加美观,开发更加便捷

页面信息的代码如下:

创建一个servlet来接收请求,获取所有的产品信息

在IDEA中,创建servlet如下图所示

在这里不勾选自动生成注解

点击ok之后,IDEA会自动跳转到web.xml文件中,自动写好了Servlet的全路径名,只需写url-pattern即可

注意url-pattern需要写得与ajax请求中的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 {

//处理响应与请求的乱码

request.setCharacterEncoding("utf-8");

response.setContentType("text/html;charset=utf-8");

//由于是显示所有的产品信息,没有参数接收

//需要调用服务层查找所有数据的方法,获取结果,响应给客户端

ProductService service = new ProductService();

try {

//调用业务层的方法,获取所有的商品

List allProuct = service.findAllProuct();

//把得到的数据,转为json类型的数据

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层获取数据,返回给web层的Servlet

web层调用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层获取数据,返回数据给web层

public List findAllProuct() throws SQLException {

ProductDao dao = new ProductDao();

//调用dao层查询所有的商品

List allProduct = dao.findAllProduct();

return allProduct;

}

}

在dao层从服务器中查询数据,给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层专门负责数据库操作

public class ProductDao {

//===========查询所有商品信息

public List findAllProduct() throws SQLException {

//利用dbutils,创建QueryRunner核心对象

QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());

//书写sql语句,查询所有的商品

String sql = "select * from product";

//把商品到的商品,转为list集合,泛型为product

List products = qr.query(sql, new BeanListHandler<>(Product.class));

return products;

}

}

dao层拿到数据后,传递给service层,service层再传递给web层的servlet,servlet拿到数据后,是保存在list集合中的,再把list集合转为json数据类型,写给浏览器.前端页面中的如下代码,就是在解析servlet返回的json数据

$.post(url,function (data) {

//解析服务器端传过来的全部数据

//============================向表格中展示商品信息

var products = eval(data);

//遍历数据

for (var i = 0; i < products.length; i++) {

//遍历每一行的数据

var protd =$("

// 并添加到表格中,添加数据到表格中

$("#tab").append(protd);

}

},"json")

通过谷歌浏览器自带的抓包工具,可以看到servlet响应的数据

把响应的数据全部复制下来,就是如下的数据.一个数组中嵌套了产品的对象.

对象中都是以键值对的形式存在的.

例如第一个数据中,键为count,值为100. 键为id,值为1,键为name,值为电视机,键为price 值为2000

[

{"count":100,"id":1,"name":"电视机","price":2000},

{"count":200,"id":2,"name":"洗衣机","price":1000},

{"count":300,"id":3,"name":"空调","price":3000},

{"count":50,"id":4,"name":"投影仪","price":2000},

{"count":1000,"id":5,"name":"HP电脑","price":4000},

{"count":100,"id":6,"name":"苹果手机","price":5000},

{"count":60,"id":7,"name":"缝纫机","price":2000},

{"count":100,"id":8,"name":"小米盒子","price":2200},

{"count":300,"id":9,"name":"饮水机","price":2000},

{"count":200,"id":10,"name":"净水器","price":2000},

{"count":500,"id":11,"name":"电暖器","price":2000},

{"count":100,"id":12,"name":"榨汁机","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":"豆浆机","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}

]

不分页的情况下,展示的效果如下:

一个页面中,把所有的数据都展示出来了,如果数据非常多,例如上百度搜索一个关键词,结果可能有上万上亿条,一次性从数据库中,拿这么多的结果给浏览器,是很长的时间的,用户体验极差,因此需要分页技术.采用物理分页,

一次只从数据库中查询当前页面需要的信息.

第三步:传递当前页面数和每页显示的数量给服务器

html页面中需要增加当前页面数和每页显示的数量这两个变量,传递给服务器

更改代码的如下图所示:

在servlet层需要接收参数,并且从service层查询对应的当前页的数据,代码如下:

public class Product extends HttpServlet {

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

//处理响应与请求的乱码

request.setCharacterEncoding("utf-8");

response.setContentType("text/html;charset=utf-8");

//当前页面

int pageNo = Integer.parseInt(request.getParameter("pageNo"));

//每页的显示条数

int pageSize = Integer.parseInt(request.getParameter("pageSize"));

//由于是显示所有的产品信息,没有参数接收

//需要调用服务层查找所有数据的方法,获取结果,响应给客户端

ProductService service = new ProductService();

try {

//根据当前页和每页显示的数目,来从service层,获取数据

List 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层新增的查找当前页面数据方法

public List findProduct(int pageNo, int pageSize) throws SQLException {

ProductDao dao = new ProductDao();

List product = dao.findProduct(pageNo, pageSize);

return product;

}

dao层新增的从数据库查找当前页面的方法

public List findProduct(int pageNo, int pageSize) throws SQLException {

QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());

String sql ="select * from product limit ?,?";

//limit第一个参数:从数据库中的哪里开始查,索引是从0开始的

//第二个参数:每次查多少个

//第一个参数的规律是:当前页数减一,乘以每页查询的个数

List productList = qr.query(sql, new BeanListHandler<>(Product.class), (pageNo - 1) * pageSize, pageSize);

return productList;

}

浏览器端显示如下图所示:每次只会显示pageSize(当前的值为6)个数的商品信息.

但是还不能动态的通过点击页面按钮来实现翻页.

那么就要考虑页面如何显示分页条以及数据该如何封装?

我们知道页面的分页条 显示 的页数是动态变化的 ,总页数 =数据的总条数/每页显示的数据,要向上取整。也就是说,我们的页面除了需要List数据之外,还需要数据的总条数、总页数、当前页、每页显示数量。另外当前页pageNo也是动态变化的,在页面上点击多少页,pageNo就是几。所以, 我们需要再创建一个javabean(PageBean.java)来封装这些数据 ,在服务端得到这些数据之后转成json数据发送给客户端显示。

第四步:将页面的相关数据封装为一个JavaBean

在domain包内创建一个类,名为PageBean,属性如下:

private int pageNo;//当前页数

private int pageSize;//每页显示的数量

private int totalCount;//一共有多少个商品信息数据

private int totalPage;//一共有多少页数据

private List products;//商品信息数据的集合

在web层传递service层当前页面数(pageNo),和每页显示的条数(pageSize),返回给web层一个PageBean

web层的最终代码如下

public class Product extends HttpServlet {

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

//处理响应与请求的乱码

request.setCharacterEncoding("utf-8");

response.setContentType("text/html;charset=utf-8");

//当前页面

int pageNo = Integer.parseInt(request.getParameter("pageNo"));

//每页的显示条数

int pageSize = Integer.parseInt(request.getParameter("pageSize"));

//由于是显示所有的产品信息,没有参数接收

//需要调用服务层查找所有数据的方法,获取结果,响应给客户端

ProductService service = new ProductService();

try {

/* 调用业务层的方法,获取所有的商品

List allProuct = service.findAllProuct();

把得到的数据,转为json类型的数据

String jsonString = JSONObject.toJSONString(allProuct);*/

//根据当前页和每页显示的数目,来从service层,获取数据

//List product = service.findProduct(pageNo, pageSize);

//===============从web层拿到pagebean的数据=================================

PageBean pageBean = service.findPageInfo(pageNo, pageSize);

//===============把数据转为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层获取商品的信息数据,LIst集合,还需要获取总的商品信息数据totalCount.总共有多少页可以通过总数据除以每页显示的数据,并向上取整.

service层的最终代码如下:

public class ProductService {

//在service层,从dao层获取数据,返回数据给web层

//=========Service层处理所有商品信息的数据给web层====================

public List findAllProuct() throws SQLException {

ProductDao dao = new ProductDao();

//调用dao层查询所有的商品

List allProduct = dao.findAllProduct();

return allProduct;

}

//============service层查询某个特定页面的数据给web层=================================

public List findProduct(int pageNo, int pageSize) throws SQLException {

ProductDao dao = new ProductDao();

List product = dao.findProduct(pageNo, pageSize);

return product;

}

//============service层封装pagebean数据===================================

public PageBean findPageInfo(int pageNo, int pageSize) throws SQLException {

ProductDao dao = new ProductDao();

List product = dao.findProduct(pageNo, pageSize);

int totalCount = dao.findTotalCount();

PageBean pb = new PageBean();

//封装数据

pb.setTotalCount(totalCount);

pb.setPageNo(pageNo);

pb.setPageSize(pageSize);

pb.setProducts(product);

//向上取整,计算总页数,不要忘了乘以1.0,否则会少一页数据

int totalPage = (int) Math.ceil(totalCount*1.0/pageSize);

pb.setTotalPage(totalPage);

//把数据给servlet

return pb;

}

}

在dao层,新增了一个方法,用于查询数据库总信息的总个数

dao层最终的代码如下

//=================dao层专门负责数据库操作

public class ProductDao {

//===========查询所有商品信息

public List findAllProduct() throws SQLException {

//利用dbutils,创建QueryRunner核心对象

QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());

//书写sql语句,查询所有的商品

String sql = "select * from product";

//把商品到的商品,转为list集合,泛型为product

List products = qr.query(sql, new BeanListHandler<>(Product.class));

return products;

}

//=======================查询当前页的产品信息=====================

public List findProduct(int pageNo, int pageSize) throws SQLException {

QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());

String sql ="select * from product limit ?,?";

//limit第一个参数:从数据库中的哪里开始查,索引是从0开始的

//第二个参数:每次查多少个

//第一个参数的规律是:当前页数减一,乘以每页查询的个数

List productList = qr.query(sql, new BeanListHandler<>(Product.class), (pageNo - 1) * pageSize, pageSize);

return productList;

}

//===============查询总共有多少条数据=================

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标签的下面,增加一行,提供分页的组件.并把li代码注释掉,因为需要动态展示.

先声明需要接收的参数变量

var url ="/ajax_product/product";

var pageNo=1;//当前页面设置为1

var pageSize=6;//每页显示6条商品信息

var totalPage;//一共有多少页数据

var products;//商品的数据信息

写好了ajax的post请求之后,抓包测试浏览器是否接收到数据

$.post(

url,//给服务器传送数据的地址

{"pageNo": pageNo, "pageSize": pageSize},//给浏览器传递当前页面数和每页显示的条数

function (data) {})

在抓包拿到了如下 的数据

{"pageNo":1,

"pageSize":6,

"products":[{"count":100,"id":1,"name":"电视机","price":2000},

{"count":200,"id":2,"name":"洗衣机","price":1000},

{"count":300,"id":3,"name":"空调","price":3000},

{"count":50,"id":4,"name":"投影仪","price":2000},

{"count":1000,"id":5,"name":"HP电脑","price":4000},

{"count":100,"id":6,"name":"苹果手机","price":5000}],

"totalCount":22,

"totalPage":3}

说明服务器端能够正常给浏览器响应数据.再接着写前端代码

显示表格中的数据

先将后端得到的数据解析,再同步到js代码中,通过pagebean.products获得所有product对象的数据的数组,再遍历这个数组,把product属性的值拼接到表格中去.

代码如下

$.post(

url,//给服务器传送数据的地址

{"pageNo": pageNo, "pageSize": pageSize},//给浏览器传递当前页面数和每页显示的条数

function (data) {

//解析服务器端传过来的全部pagebean数据,格式为json类型

var pagebean = eval(data);

//同步数据

pageNo=pagebean.pageNo;

pageSize=pagebean.pageSize;

totalPage=pagebean.totalPage;

products=pagebean.products;

//显示表格中的数据===============================================

for (var i = 0; i < products.length; i++) {

//遍历每一行的数据

var protd =$("

// 并添加到表格中,添加数据到表格中

$("#tab").append(protd);

}

},"json")

这段代码写完后,可开启服务器,测试能否获取数据到表格中.经测试成功显示数据.

显示分页条的数据

先显示上一页与下一页的数据

//显示分页条的数据

//先不考虑功能,先能显示出来

//显示上一页

var preLi=$('

//通过类选择器,添加进去

$(".pager").append(preLi);

//显示下一页

var nextLi=$('

//通过类选择器,添加进去

$(".pager").append(nextLi);

进测试效果如下:

显示页码数据:

//显示分页条的数据

//先不考虑功能,先能显示出来

//显示上一页

var preLi=$('

//通过类选择器,添加进去

$(".pager").append(preLi);

//遍历显示页码

for (var i = 1; i <= totalPage; i++) {

//创建li标签

var li=$('

//通过类选择器,添加到ul中

$(".pager").append(li);

}

//显示下一页

var nextLi=$('

//通过类选择器,添加进去

$(".pager").append(nextLi);

效果如下图所示:

当前页高亮显示

由于bootstrap中,pager类不支持高亮显示,因此把分页的类换为pagination.

高亮的逻辑是,在遍历的是否,判断是否为当前页(pageNo).

给li标签添加class的active 属性

//遍历显示页码

for (var i = 1; i <= totalPage; i++) {

var li;

if(i===pageNo){

//=========是当前页,就高亮显示

li=$('

//通过类选择器,添加到ul中

$(".pagination").append(li);

}else{

//========不是当前页,不高亮显示

li=$('

//通过类选择器,添加到ul中

$(".pagination").append(li);

}

}

效果如下

给页码添加点击事件,切换数据.

当前页不需要添加点击事件

给页数里面的a标签添加onclick事件,绑定一个skipPage()函数,skipPage()函数里面所做的操作实际上就是我们获取第1页数据的向服务器发送Ajax的post请求的操作,所以 把$(function(){})的代码复制到skipPage()函数中 ,然后在页面加载完成时调用skipPage()函数,传入1就表示默认加载第1页数据。此时,$(function(){})只会执行一次.而skipPage()成了递归函数,自己调用自己.但一次点击事件,只会调用一次skipPage方法,与java中的递归不太一样.

执行完此段代码后,点击不同的代码,发现表格的内容以及分页条会不断叠加

如下图所示:

每次加载数据时,清空数据. 清空分页条

添加了清空分页条的代码后,发现,分页条没有叠加了,但是表格还在叠加

清空表格

$("#tab").empty(); 给表格执行清空代码后发现如下现象:

表格的第一行标题没有了,所以需要用选择器,把第一行排除在外.

$("#tab tr:not(:first)")的含义是

先根据id选择器,选择表格

再由层级选择器,选择tr行

再由基本选择器not中嵌套基本选择器first,代表不是第一行

整体的意思是,选择了表格了不是第一行的元素,调用empty()方法,删除匹配的元素集合中所有的子节点。

测试后,能够不删除第一行数据

上一页判断是否可用,以及切换页码功能

如果当前页是第一页,上一页功能就不可用.

如果当前页不是第一页,就添加点击事件,切换到上一页,把页码减一.

//显示上一页,判断是否可用

var preLi;

if(pageNo===1){

//如果当前页是第一页,上一页功能就不可用

preLi=$('

}else{

preLi=$('

}

//通过类选择器,添加进去

$(".pagination").append(preLi);

下一页判断是否可用,以及切换页码功能

如果当前页是最后一页,上一页功能就不可用.

如果当前页不是最后一页,就添加点击事件,切换到下一页,把页码加一.

//显示下一页,判断是否可用

var nextLi;

if(pageNo===totalPage){

//如果当前页是最后一页,上一页功能就不可用.

nextLi=$('

}else {

//如果当前页不是最后一页,就添加点击事件,切换到上一页,把页码减一.

nextLi=$('

}

//通过类选择器,添加进去

$(".pagination").append(nextLi);

至此,前端页面的代码全部完成,功能全部实现

前端页面的全部代码如下

总结

此分页功能,用到了JavaEE的三层架构的思想.每一层各司其职,做各自的负责的事情.前端部分为难点.需要处理的细节很多.前端涉及到了ajax和jquery.jQuery的一些语法与选择器的相关的东西要非常熟练.还用到了bootrap响应式开发,让前端页面的布局更加方便.


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:在线测试接口地址(接口测试工具在线)
下一篇:SpringBoot 整合Redis 数据库的方法
相关文章

 发表评论

暂时没有评论,来抢沙发吧~