@目录

什么是分页 ?

两个子模块功能的问题分析 和 解决方案

有条件查和无条件查询的影响 和 解决方案

项目案例: mysql + commons-dbutils+itcast-tools+BaseServlet + 分页+JSP+JSTL+EL+MVC模式


什么是分页?

如上所示,就是分页  ,不用多说了

子模块功能的问题分析 和 解决方案

@总功能分析  常规JDBC中,点击查询或输入条件查询,在页面中可显示查询出的所有记录,有多少记录就显示多少。在这种项目的基础上增加分页功能 。 @分页功能的宗旨 是无论什么样的查询,显示出的记录都是当前页的记录 。  所以,我们必须得向系统说明我们当前是要显示第几页的数据 。  自然,需要一个PageBean类

public class PageBean<T> {private int pageCode ;//当前页码
//        private int totalPage ;//总页数,总页数应该由计算获取private int totalRecord;//总记录数private int pageSize;//每页记录数,这是参数是定做这个软件的甲方提出来的,在Servlet中直接定义为10了private List<T> beanList;//当前页的记录集合,方便整页记录的转移private String url ;//Url后的条件,条件查询设置的
}

这个PageBean类中封装了当前页、总记录数、当前页所有记录的集合等,系统通过当前页码这个参数返回pageSize条记录放在beanList集合中返回显示。

@子模块功能1 中首页的pageCode是1,尾页的pageCode是totalPage,上一页和下一页分别是pageCode-1 和pageCode+1 。

@子模块功能2 先来分析一个功能 : 当前页在页码列表中是第几个位置 ?

从上述两张图片中,点击1页码,当前页处于列表的第1个位置,点击2页码,当前页处于列表的第2个位置,..........,点击6页码,当前页处于列表的第6个位置,但是当点击7页码时,当前页还是处于列表的第6个位置 。 也就是说,假如每次一行只能显示10个页码,1~6页码的当前页的位置还是1~6,列表从页码1~页码10。   但是7~10页码的当前页的位置始终位于页码列表的第6个位置 ,列表从【页码2~页码11】~【页码X~页码totalPage】。其实非常好解决  ,列表头尾的判定 还是利用pageCode , begin = pageCode - 5   ,  end = pageCode + 4  。

@解决

  • 如果  totalPage  <=  10(列表长度),那么  begin  =  1,end  =  totalPage ;
  • 使用公式计算;begin  =  pc-5    ,    end  =   pc   +   4;
  • 头溢出:当  begin  <  1  时   ,   让  begin  =  1 ;
  • 尾溢出:当   end  >  totalPage  时   ,   让  end  =  totalPage   

有条件查和无条件查询的影响 和 解决方案

@产生一个问题  分页使得有条件查询产生一个严重问题 , 通过条件查询出40条记录,分4页显示,只有第一页是该条件下的记录,其余3页都是不带条件的记录 。所以我们必须告诉系统我们的条件是什么,每一页都要带着条件去查询和返回  。

@解决 在pageBean中设置url参数 , 这个参数将会携带这条件传递到Servlet中 。

项目案例(mvc+jdbc+c3p0+BaseServlet+mysql+JSP+EL+JSTL)

@使用   mysql数据库,c3p0数据库连接池,

采用commons-dbutils组件,封装好的JdbcUtils工具类和TxQueryRunner工具类辅助JDBC ,  (学习地址 : http://www.cnblogs.com/zyuqiang/p/7218083.html)

BaseServlet辅助类

JSP+EL+JSTL

@数据库

1 CREATE TABLE t_customer (
2    username VARCHAR(50) DEFAULT NULL,
3    age INT(11) DEFAULT NULL,
4    balance DOUBLE(20,5) DEFAULT NULL
5 );

t_customer

@源码

 1 package cn.kmust.pagination.customer.domain;
 2 /**
 3  * 实体类
 4  *    变量名字与数据库中对应字段名一样,便于封装操作
 5  * @author ZHAOYUQIANG
 6  *
 7  */
 8 public class Customer {
 9     private String username ; //用户
10     private int age ;  //年龄
11     private double balance ; //资金
12     public String getUsername() {
13         return username;
14     }
15     public void setUsername(String username) {
16         this.username = username;
17     }
18     public int getAge() {
19         return age;
20     }
21     public void setAge(int age) {
22         this.age = age;
23     }
24     public double getBalance() {
25         return balance;
26     }
27     public void setBalance(double balance) {
28         this.balance = balance;
29     }
30     @Override
31     public String toString() {
32         return "Customer [username=" + username + ", age=" + age + ", balance="
33                 + balance + "]";
34     }
35     public Customer(String username, int age, double balance) {
36         super();
37         this.username = username;
38         this.age = age;
39         this.balance = balance;
40     }
41     public Customer() {
42         super();
43         // TODO Auto-generated constructor stub
44     }
45
46
47
48
49 }

Customer

 1 package cn.kmust.pagination.pageBean.domain;
 2 import java.util.List;
 3 import java.util.List;
 4 /**
 5      * 分页Bean
 6      *    把每一页中的当前页码、总页数、总记录数、每页记录数、当前页的记录集合等参数
 7      *       封装到该类的一个对象中,形成PageBean对象
 8      * @author ZHAOYUQIANG
 9      *
10      */
11     public class PageBean<T> {
12         private int pageCode ;//当前页码
13 //        private int totalPage ;//总页数,总页数应该由计算获取
14         private int totalRecord;//总记录数
15         private int pageSize;//每页记录数,这是参数是定做这个软件的甲方提出来的,在Servlet中直接定义为10了
16         private List<T> beanList;//当前页的记录集合,方便整页记录的转移
17         private String url ;//Url后的条件,条件查询设置的
18
19         public String getUrl() {
20             return url;
21         }
22         public void setUrl(String url) {
23             this.url = url;
24         }
25         public int getPageCode() {
26             return pageCode;
27         }
28         public void setPageCode(int pageCode) {
29             this.pageCode = pageCode;
30         }
31         /*
32          * 计算总页数,这个页数是由总记录和每页记录数决定的
33          */
34         public int getTotalPage() {
35             int totalPage = totalRecord/pageSize ;
36             return totalRecord%pageSize==0 ? totalPage : totalPage+1;
37         }
38         public int getTotalRecord() {
39             return totalRecord;
40         }
41         public void setTotalRecord(int totalRecord) {
42             this.totalRecord = totalRecord;
43         }
44         public int getPageSize() {
45             return pageSize;
46         }
47         public void setPageSize(int pageSize) {
48             this.pageSize = pageSize;
49         }
50         public List<T> getBeanList() {
51             return beanList;
52         }
53         public void setBeanList(List<T> beanList) {
54             this.beanList = beanList;
55         }
56
57 }

PageBean

  1 package cn.kmust.pagination.customer.servlet;
  2
  3 import java.io.IOException;
  4 import java.io.UnsupportedEncodingException;
  5
  6 import javax.servlet.ServletException;
  7 import javax.servlet.http.HttpServletRequest;
  8 import javax.servlet.http.HttpServletResponse;
  9
 10 import cn.itcast.commons.CommonUtils;
 11 import cn.itcast.servlet.BaseServlet;
 12 import cn.kmust.pagination.customer.domain.Customer;
 13 import cn.kmust.pagination.customer.service.CustomerService;
 14 import cn.kmust.pagination.pageBean.domain.PageBean;
 15 /**
 16   * Web层
 17   *   继承了我们自己写的BaseServlet类
 18   *   要求写的方法得与service()相同,
 19   *     并且.jsp页面必须传递过来一个method参数,如(add、deleter等)
 20   *
 21   * @author ZHAOYUQIANG
 22   *
 23 */
 24 public class CustomerServlet extends BaseServlet {
 25     /*
 26      * 依赖CustomerService
 27      */
 28     private CustomerService cstmService = new CustomerService();
 29     /**
 30      * 客户查询所有
 31      *    加入了分页功能 : 向页面返回当前页的所有记录, 返回的是一个对象,对象中封装了一个beanList集合
 32      *         该集合中存放这当前页所有记录
 33      * @param request
 34      * @param response
 35      * @return
 36      * @throws ServletException
 37      * @throws IOException
 38      */
 39     public String queryAll(HttpServletRequest request, HttpServletResponse response)
 40             throws ServletException, IOException {
 41         /*
 42          * 1. 获取list.jsp页面传递的pc
 43          * 2. 给定每页记录数ps = 10 。开发者根据客户的需求,认为规定的
 44          * 3. 使用pc和ps调用sevice方法,得到当前页的PageBean对象(该对象中封装了
 45          *         当前页的所有记录的集合等)
 46          * 4. 把PageBean保存到request域中
 47          * 5. 转发到list.jsp
 48          *
 49          */
 50         int pageCode = getCurrentPage(request);
 51         int pageSize = 10 ; //每页10记录
 52         PageBean<Customer> pageBean = cstmService.queryAll(pageCode,pageSize);
 53         /*
 54          * 因为与条件查询共用一个list.jsp,所以也需要加url
 55          */
 56         pageBean.setUrl(getUrl(request));
 57         request.setAttribute("pageBean", pageBean);
 58         return "f:/list.jsp";
 59
 60     }
 61
 62
 63     /**
 64      * 条件查询
 65      *    具有分页功能,按照条件查询,条件也会被带入分页中
 66      * @param request
 67      * @param response
 68      * @return
 69      * @throws ServletException
 70      * @throws IOException
 71      */
 72     public String query(HttpServletRequest request, HttpServletResponse response)
 73             throws ServletException, IOException {
 74         /*
 75          * 1. 封装表单数据到Customer对象中
 76          *       只有一个属性username,是查询的条件critaria
 77          * 2. 得到当前页码 pageCode
 78          * 3. 给定pageSize 10
 79          * 4. 使用pageCode和pageSize以及条件对象,调用service方法得到query,
 80          *            返回当前页的PageBean对象,内封装了当前页的所有记录集合
 81          * 5. 把PageBean保存到request域中
 82          * 6. 转发到list.jsp显示成功信息
 83          */
 84         Customer criteria = CommonUtils.toBean(request.getParameterMap(), Customer.class);
 85         /*
 86          * 处理GET请求方式编码问题
 87          *    因为query.jsp表单使用的是get提交方法
 88          */
 89         criteria = encoding(criteria);
 90
 91         int pageCode = getCurrentPage(request);
 92         int pageSize = 10 ; //每页10记录
 93         PageBean<Customer> pageBean = cstmService.query(criteria,pageCode,pageSize);
 94         /*
 95          * 得到url,保存到pageBean对象中
 96          */
 97         pageBean.setUrl(getUrl(request));
 98         request.setAttribute("pageBean", pageBean);
 99         return "f:/list.jsp";
100     }
101
102
103     /**
104      * 处理GET请求乱码
105      *    因为BaseSevlet类中只有处理POST请求的乱码,没有GET请求的乱码处理
106      * @param criteria
107      * @return
108      * @throws UnsupportedEncodingException
109      */
110     private Customer encoding(Customer criteria) throws UnsupportedEncodingException {
111         String username = criteria.getUsername();
112
113         if(username != null && !username.trim().isEmpty()){
114             username = new String(username.getBytes("ISO-8859-1"),"utf-8");
115             criteria.setUsername(username);
116         }
117         return criteria;
118     }
119
120
121
122
123     /**
124      * 获取pageCode(当前页码)
125      *     传递到Servlet中的参数都是String类型的,所以需要转换
126      *     pageCode参数如果不存在,说明是第一次调用,当前页码默认为第一页
127      * @param request
128      * @return
129      */
130     private int getCurrentPage(HttpServletRequest request){
131         String value = request.getParameter("pageCode");
132         if(value == null || value.trim().isEmpty()){
133             return 1 ;
134         }
135         return Integer.parseInt(value);
136     }
137
138
139     /**
140      * 截取url
141      *   条件查询中需要使用
142      *    /项目名/Servlet路径?参数字符串
143      * @param request
144      * @return
145      */
146     private String getUrl(HttpServletRequest request){
147         /*
148          * 1. 获取项目名
149          * 2. 获取Servlet路径
150          * 3. 获取参数列表
151          *       这个参数是条件
152          */
153         String contextPath = request.getContextPath();
154         String servletPath = request.getServletPath();
155         String queryString = request.getQueryString();
156         /*
157          * 4. 判断是否包含pageCode参数
158          *      如果包含需要剪掉,不要这个参数
159          */
160         if(queryString.contains("&pageCode")){
161             int index = queryString.lastIndexOf("&pageCode");
162             queryString = queryString.substring(0,index);
163         }
164         return contextPath+servletPath+"?"+queryString ;
165     }
166
167 }

CustomerServlet

 1 package cn.kmust.pagination.customer.service;
 2
 3 import java.sql.SQLException;
 4 import java.util.List;
 5
 6 import cn.itcast.jdbc.JdbcUtils;
 7 import cn.kmust.pagination.customer.dao.CustomerDao;
 8 import cn.kmust.pagination.customer.domain.Customer;
 9 import cn.kmust.pagination.pageBean.domain.PageBean;
10
11
12
13 /**
14  * service 层   处理业务
15  * @功能
16  *       1. 条件查询
17  *       2. 查询 所有用户
18  *       3. 查询 所有记录行数
19  * @author ZHAOYUQIANG
20  *
21  */
22 public class CustomerService {
23     /*
24      * 依赖CustomerDao
25      */
26     CustomerDao cstmDao = new CustomerDao();
27     /**
28      * 条件查询
29      *
30      * @param criteria
31      * @param pageCode
32      * @param pageSize
33      * @return
34      */
35     public PageBean<Customer> query(Customer criteria,int pc,int ps) {
36            return  cstmDao.query(criteria,pc,ps);
37         }
38     /**
39      * 查询所有客户业务
40      *  具有分页功能 : 返回PageBean对象 ,对象中封装了 当前页所有记录的集合
41      * @param pc
42      * @param ps
43      * @return
44      */
45     public PageBean<Customer> queryAll(int pc,int ps){
46         return cstmDao.queryAll(pc,ps);
47     }
48
49
50
51 }

CustomerService

  1 package cn.kmust.pagination.customer.dao;
  2
  3 import java.sql.ResultSet;
  4 import java.sql.SQLException;
  5 import java.util.ArrayList;
  6 import java.util.List;
  7 import java.util.Map;
  8
  9 import javax.sql.DataSource;
 10
 11 import org.apache.commons.dbutils.QueryRunner;
 12 import org.apache.commons.dbutils.ResultSetHandler;
 13 import org.apache.commons.dbutils.handlers.BeanHandler;
 14 import org.apache.commons.dbutils.handlers.BeanListHandler;
 15 import org.apache.commons.dbutils.handlers.MapHandler;
 16 import org.apache.commons.dbutils.handlers.MapListHandler;
 17 import org.apache.commons.dbutils.handlers.ScalarHandler;
 18
 19 import cn.itcast.jdbc.JdbcUtils;
 20 import cn.itcast.jdbc.TxQueryRunner;
 21 import cn.kmust.pagination.customer.domain.Customer;
 22 import cn.kmust.pagination.pageBean.domain.PageBean;
 23
 24
 25
 26
 27 /**
 28  *dao层
 29  *    对数据库的操作
 30  * @author ZHAOYUQIANG
 31  *
 32  */
 33 public class CustomerDao {
 34     private QueryRunner qr = new TxQueryRunner();
 35     /**
 36      * 对数据库进行查询所有客户操作
 37      *   具有分页功能  : 返回PageBean对象,该对象封装了当前页的所有记录的集合
 38      *      当前页的所有记录都放到beanList集合中,然后随当前页码等参数封装到pageBean中返回
 39      * @return
 40      */
 41     public PageBean<Customer> queryAll(int pc,int ps){
 42         try {
 43             /*
 44              * 有关数据库的操作:
 45              *     准备sql模版
 46              *     调用QueryRunner的query方法
 47              */
 48             /*该方法的任务:
 49              *  1. 创建PageBean对象
 50              */
 51             PageBean<Customer> pageBean = new PageBean<Customer>();
 52             /*
 53              * 2. 设置pc和ps,封装到我pageBean对象
 54              */
 55             pageBean.setPageCode(pc);
 56             pageBean.setPageSize(ps);
 57             /*
 58              *  3. 查询数据库得到totalRecord(数据库所有记录),封装到我pageBean对象
 59              */
 60             String sql = "select count(*) from t_customer";
 61             Number num = (Number)qr.query(sql,new ScalarHandler() );
 62             int totalRecord  = num.intValue();
 63             pageBean.setTotalRecord(totalRecord);
 64             /*
 65              * 4. 查询数据库得到BeanList(当前页记录的集合),封装到我pageBean对象
 66              *      当前页到底是第几页,当前页有多少条记录呢?
 67              *        利用mysql的limit子句, (limit 4,10的意思是从第五行记录开始(包含第五行),查询10行记录)
 68              *          很明显当前页的是从第(pc-1)*ps行开始,查询ps行记录。
 69              *          根据limit子句的特点,巧妙的设计查询当前页的数据
 70              *      用order by 通过客户姓名来排序显示
 71              */
 72             sql = "select * from t_customer order by username limit ?,?";
 73             List<Customer> beanList = qr.query(sql,
 74                     new BeanListHandler<Customer>(Customer.class),(pc-1)*ps,ps);
 75             pageBean.setBeanList(beanList);
 76             /*
 77              * 5. 返回PageBean对象
 78              */
 79             return pageBean ;
 80         } catch (SQLException e) {
 81             throw new RuntimeException(e);
 82         }
 83     }
 84     /**
 85      * 条件查询
 86      *   具有分页功能
 87      * @param criteria
 88      * @param pc
 89      * @param ps
 90      * @return
 91      */
 92     public PageBean<Customer> query(Customer criteria,int pc,int ps) {
 93         try {
 94             /*
 95              * 1. 创建PageBean对象
 96              * 2. 设置已有属性,pc和ps(pageCode和pageSize)
 97              * 3. 通过条件查询数据库得到totalRecord
 98              * 4. 查询数据库,返回beanList(当前页记录的集合)
 99              */
100             PageBean<Customer> pageBean = new PageBean<Customer>();
101             pageBean.setPageCode(pc);
102             pageBean.setPageSize(ps);
103             /*
104              * 3. 通过条件查询数据库得到totalRecord
105              */
106             String sql1 = null;
107             String username = criteria.getUsername();
108             if(username != null && !username.trim().isEmpty()){
109                 sql1 = "select count(*) from t_customer where username like ?" ;
110             }
111             Object[] params1 = {"%"+username+"%"};
112             /*
113              * 3.3. 得到totalRecord
114              */
115             Number num = (Number)qr.query(sql1,
116                     new ScalarHandler(),params1);
117             int totalRecord = num.intValue();
118             pageBean.setTotalRecord(totalRecord);
119             /*
120              * 4. 查询数据库,返回beanList(当前页记录的集合)
121              *    还是需要拼凑sql语句,并且需要limit子句
122              *      params中需要给出limit后两个问号对应的值
123              *
124              */
125
126             String sql2 = "select * from t_customer where username like ? limit ?,?";
127
128             Object[] params = {"%"+username+"%",(pc-1)*ps,ps};
129             List<Customer> beanList = qr.query(sql2,
130                     new BeanListHandler<Customer>(Customer.class),
131                     params);
132             pageBean.setBeanList(beanList);
133             return pageBean ;
134         } catch (SQLException e) {
135             throw new RuntimeException(e);
136         }
137
138     }
139 }

CustomerDao

@项目download   http://files.cnblogs.com/files/zyuqiang/jdbcStudy_Demo5_pagination.rar

转载于:https://www.cnblogs.com/zyuqiang/p/7235548.html

《JavaWeb从入门到改行》分页功能的实现相关推荐

  1. 《JavaWeb从入门到改行》过滤器学习笔记

    目录:(点击红色方框展开子目录) Filter API 无 Filter详解 过滤器配置 四种拦截方式 经典案例 分IP统计网站的访问次数 粗粒度权限控制 解决全站字符乱码 页面静态化 使用@WebF ...

  2. 《JavaWeb从入门到改行》注册时向指定邮箱发送邮件激活

    javaMail API javaMail是SUN公司提供的针对邮件的API . 两个jar包  mail.jar 和 activation.jar java mail中主要类:javax.mail. ...

  3. 《JavaWeb从入门到改行》JDBC经典秘方QueryRunner

    目录: 基础篇_功能各自回顾 JDBC基础代码回顾(使用JdbcUtils工具简化) c3p0数据库连接池的使用(使用JdbcUtils工具简化) 大数据的插入(使用c3p0+JdbcUtils工具简 ...

  4. 《JavaWeb从入门到改行》fileupload,没毛病

    目录: »  fileupload API >  文件上传的要求 >  fileupload组件 »  上传细节的代码演示 »  项目案例-上传头像并显示 fileupload API 文 ...

  5. 《JavaWeb从入门到改行》多重外键关系在java中的处理方案

    目录:(点击红色方框展开子目录) 问题描述 无 项目案例说明 业务描述 数据库说明 项目源码及下载 无 问题描述 如上两图,数据库中各个表之间有很多的外键关系,其中业务关系是一个用户下有该用户的订单, ...

  6. 复习JavaWeb的小项目书籍信息的增删改查分页功能实现Java面试题Session和Cookie的基础概念生活【记录一个咸鱼大学生三个月的奋进生活】034

    记录一个咸鱼大学生三个月的奋进生活034 JavaWeb的增删改查分页功能实现 前期准备工作(数据库连接类和实体类) 数据库建立 数据库连接类(DBManager) 书籍信息的实体类(Book) 操作 ...

  7. Spring Boot入门系列(十六)整合pagehelper,一秒实现分页功能!

    之前讲了Springboot整合Mybatis,然后介绍了如何自动生成pojo实体类.mapper类和对应的mapper.xml 文件,并实现最基本的增删改查功能.接下来要说一说Mybatis 的分页 ...

  8. JavaWeb.09.新闻之分页功能

    怎么实现分页功能? 目录: 关于分页? 实现数据分页? 分页优化: 模糊查询的优化: 数据库编写SQL语句?         具体代码展示? 关于分页: 在实现分页功能之前,咱们可以先将主页(inde ...

  9. javaWeb网页分页功能

    分页主要功能 采用分页技术让数据分批显示,当一页数据太多用户观看体验不佳,就可以使用分页技术 实现分页三部曲 一.确定每一页数据的条数 二.计算页数的数量 三.实现分页的sql语句 3.案例:使用分页 ...

最新文章

  1. 都 2020 年了,这些 OKR 的坑你还要踩吗?
  2. 鸿蒙 意识结晶,意识的无限性
  3. java怎么设置不同事件_activiti 全局流程监听ActivitiEventListener,实现监听不同类型事件,不需要在acitivit中配置任务监听,非常方便...
  4. 网页登录接口php,thinkphp-登入接口示例
  5. Google Megastore介绍
  6. MySQL的timestamp字段可以使用的范围是多少
  7. 专科python应届生工资多少-大四应届毕业生,学了两个月Python,找工作感觉好难啊?...
  8. python名片管理系统_Python名片管理系统
  9. Log4j和Slf4j的比较
  10. dataframe 如何选中某列的一行_Spark中的RDD、DataFrame和DataSet讲解
  11. linux工作区切换到桌面,linux切换桌面环境 gnome kde
  12. php怎么将农历转换成公历,php农历转公历怎么实现
  13. 淘宝秒杀半价前N名半价商品
  14. canvas 的绘图模式 retained-mode(保存模式) 和 immediate-mode (立即模式)
  15. UTC时间和CST时间
  16. html中哪些字体不识别中文字体,div字体_正确设置div兼容的汉字中文字体
  17. bindec() 函数
  18. 关于消防设施的RFID资产管理,RFID消防设施资产管理-新导智能
  19. 【ROM制作工具】V1.0.0.23新版全新发布啦
  20. 三八节礼物推荐,不能错过的四款数码好物推荐

热门文章

  1. win10不操作几分钟睡眠的解决
  2. 糟心叻...hystrix.stream页面输出只有ping没data
  3. 51物联卡解析!购买的物联网卡正确姿势
  4. 人脑能用计算机算法吗,计算机和人类大脑相比,谁才是“最强大脑”?
  5. 【Gatsby】Gatsby初体验
  6. 华北理工计算机考研分数线,2019华北理工大学研究生分数线汇总(含2016-2019历年复试)...
  7. 像素和分辨率的理解、位图矢量图的区别
  8. Github docker源码之代码文件docker/image的解读
  9. 红橙黄绿青蓝紫的html代码,红橙黄绿青蓝紫
  10. ObjectARX编程--圆弧