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

时间:2021-05-02

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响应式开发,可以让页面更加美观,开发更加便捷

    页面信息的代码如下:

    ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>商品展示列表</title> <!--引入bootstrap相关文件--> <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"> //页面加载时,向服务器发送请求,接收全部的商品数据 $(function () { //===================未分页,展示所有数据=============================== var url ="/ajax_product/product"; //=====向服务器发送post请求 $.post(url,function (data) { //解析服务器端传过来的全部数据 //============================向表格中展示商品信息 var products = eval(data); //遍历数据 for (var i = 0; i < products.length; i++) { //遍历每一行的数据 var protd =$("<tr><td>"+products[i].id+"</td><td>"+products[i].name+"</td><td>"+products[i].count+"</td><td>"+products[i].price+"</td></tr>"); // 并添加到表格中,添加数据到表格中 $("#tab").append(protd); } },"json") }) </script> <body> <h3 align="center">促销商品展示</h3> <div class="container"> <!--商品的表格占一行--> <div class="row"> <div class="col-md-12"> <!--table-hover表示当鼠标移入这一行表格的时候,颜色变化 table-bordered表示给表格加边框 --> <table class="table table-hover table-bordered" id="tab"> <tr> <th>编号</th> <th>商品名称</th> <th>商品数量</th> <th>商品单价</th> </tr> </table> </div> </div> </div> </body> </html>

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

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

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

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

    注意url-pattern需要写得与ajax请求中的servlet一致.

    web层servlet的代码如下:

    ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 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<com.thc.domain.product> 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层的代码如下

    ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 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<product> findallprouct() throws sqlexception { productdao dao = new productdao(); //调用dao层查询所有的商品 list<product> allproduct = dao.findallproduct(); return allproduct; } }

    在dao层从服务器中查询数据,给service层

    ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 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<product> findallproduct() throws sqlexception { //利用dbutils,创建queryrunner核心对象 queryrunner qr = new queryrunner(jdbcutils.getdatasource()); //书写sql语句,查询所有的商品 string sql = "select * from product"; //把商品到的商品,转为list集合,泛型为product list<product> products = qr.query(sql, new beanlisthandler<>(product.class)); return products; } }

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

    ? 1 2 3 4 5 6 7 8 9 10 11 12 $.post(url,function (data) { //解析服务器端传过来的全部数据 //============================向表格中展示商品信息 var products = eval(data); //遍历数据 for (var i = 0; i < products.length; i++) { //遍历每一行的数据 var protd =$("<tr><td>"+products[i].id+"</td><td>"+products[i].name+"</td><td>"+products[i].count+"</td><td>"+products[i].price+"</td></tr>"); // 并添加到表格中,添加数据到表格中 $("#tab").append(protd); } },"json")

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

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

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

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

    ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 [ {"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层查询对应的当前页的数据,代码如下:

    ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 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<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层新增的查找当前页面数据方法

    ? 1 2 3 4 5 public list<product> findproduct(int pageno, int pagesize) throws sqlexception { productdao dao = new productdao(); list<product> product = dao.findproduct(pageno, pagesize); return product; }

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

    ? 1 2 3 4 5 6 7 8 9 public list<product> findproduct(int pageno, int pagesize) throws sqlexception { queryrunner qr = new queryrunner(jdbcutils.getdatasource()); string sql ="select * from product limit ?,?"; //limit第一个参数:从数据库中的哪里开始查,索引是从0开始的 //第二个参数:每次查多少个 //第一个参数的规律是:当前页数减一,乘以每页查询的个数 list<product> productlist = qr.query(sql, new beanlisthandler<>(product.class), (pageno - 1) * pagesize, pagesize); return productlist; }

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

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

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

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

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

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

    ? 1 2 3 4 5 private int pageno;//当前页数 private int pagesize;//每页显示的数量 private int totalcount;//一共有多少个商品信息数据 private int totalpage;//一共有多少页数据 private list<product> products;//商品信息数据的集合

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

    web层的最终代码如下

    ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 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<com.thc.domain.product> 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层的最终代码如下:

    ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 public class productservice { //在service层,从dao层获取数据,返回数据给web层 //=========service层处理所有商品信息的数据给web层==================== public list<product> findallprouct() throws sqlexception { productdao dao = new productdao(); //调用dao层查询所有的商品 list<product> allproduct = dao.findallproduct(); return allproduct; } //============service层查询某个特定页面的数据给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数据=================================== 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(); //封装数据 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层最终的代码如下

    ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 //=================dao层专门负责数据库操作 public class productdao { //===========查询所有商品信息 public list<product> findallproduct() throws sqlexception { //利用dbutils,创建queryrunner核心对象 queryrunner qr = new queryrunner(jdbcutils.getdatasource()); //书写sql语句,查询所有的商品 string sql = "select * from product"; //把商品到的商品,转为list集合,泛型为product list<product> products = qr.query(sql, new beanlisthandler<>(product.class)); return products; } //=======================查询当前页的产品信息===================== public list<product> findproduct(int pageno, int pagesize) throws sqlexception { queryrunner qr = new queryrunner(jdbcutils.getdatasource()); string sql ="select * from product limit ?,?"; //limit第一个参数:从数据库中的哪里开始查,索引是从0开始的 //第二个参数:每次查多少个 //第一个参数的规律是:当前页数减一,乘以每页查询的个数 list<product> 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代码注释掉,因为需要动态展示.

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

    ? 1 2 3 4 5 var url ="/ajax_product/product"; var pageno=1;//当前页面设置为1 var pagesize=6;//每页显示6条商品信息 var totalpage;//一共有多少页数据 var products;//商品的数据信息

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

    ? 1 2 3 4 $.post( url,//给服务器传送数据的地址 {"pageno": pageno, "pagesize": pagesize},//给浏览器传递当前页面数和每页显示的条数 function (data) {})

    在抓包拿到了如下 的数据

    ? 1 2 3 4 5 6 7 8 9 10 {"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属性的值拼接到表格中去.

    代码如下

    ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 $.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 =$("<tr><td>"+products[i].id+"</td><td>"+products[i].name+"</td> <td>"+products[i].count+"</td><td>"+products[i].price+"</td> </tr>"); // 并添加到表格中,添加数据到表格中 $("#tab").append(protd); } },"json")

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

    显示分页条的数据

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

    ? 1 2 3 4 5 6 7 8 9 10 11 //显示分页条的数据 //先不考虑功能,先能显示出来 //显示上一页 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>'); //通过类选择器,添加进去 $(".pager").append(preli); //显示下一页 var next

    声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

    相关文章