《JavaWeb从入门到改行》分页功能的实现
@目录
项目案例: 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
@数据库
- CREATE TABLE t_customer (
- username VARCHAR(50) DEFAULT NULL,
- age INT(11) DEFAULT NULL,
- balance DOUBLE(20,5) DEFAULT NULL
- );
t_customer
@源码
- package cn.kmust.pagination.customer.domain;
- /**
- * 实体类
- * 变量名字与数据库中对应字段名一样,便于封装操作
- * @author ZHAOYUQIANG
- *
- */
- public class Customer {
- private String username ; //用户
- private int age ; //年龄
- private double balance ; //资金
- public String getUsername() {
- return username;
- }
- public void setUsername(String username) {
- this.username = username;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public double getBalance() {
- return balance;
- }
- public void setBalance(double balance) {
- this.balance = balance;
- }
- @Override
- public String toString() {
- return "Customer [username=" + username + ", age=" + age + ", balance="
- + balance + "]";
- }
- public Customer(String username, int age, double balance) {
- super();
- this.username = username;
- this.age = age;
- this.balance = balance;
- }
- public Customer() {
- super();
- // TODO Auto-generated constructor stub
- }
- }
Customer
- package cn.kmust.pagination.pageBean.domain;
- import java.util.List;
- import java.util.List;
- /**
- * 分页Bean
- * 把每一页中的当前页码、总页数、总记录数、每页记录数、当前页的记录集合等参数
- * 封装到该类的一个对象中,形成PageBean对象
- * @author ZHAOYUQIANG
- *
- */
- 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后的条件,条件查询设置的
- public String getUrl() {
- return url;
- }
- public void setUrl(String url) {
- this.url = url;
- }
- public int getPageCode() {
- return pageCode;
- }
- public void setPageCode(int pageCode) {
- this.pageCode = pageCode;
- }
- /*
- * 计算总页数,这个页数是由总记录和每页记录数决定的
- */
- public int getTotalPage() {
- int totalPage = totalRecord/pageSize ;
- return totalRecord%pageSize==0 ? totalPage : totalPage+1;
- }
- public int getTotalRecord() {
- return totalRecord;
- }
- public void setTotalRecord(int totalRecord) {
- this.totalRecord = totalRecord;
- }
- public int getPageSize() {
- return pageSize;
- }
- public void setPageSize(int pageSize) {
- this.pageSize = pageSize;
- }
- public List<T> getBeanList() {
- return beanList;
- }
- public void setBeanList(List<T> beanList) {
- this.beanList = beanList;
- }
- }
PageBean
- package cn.kmust.pagination.customer.servlet;
- import java.io.IOException;
- import java.io.UnsupportedEncodingException;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import cn.itcast.commons.CommonUtils;
- import cn.itcast.servlet.BaseServlet;
- import cn.kmust.pagination.customer.domain.Customer;
- import cn.kmust.pagination.customer.service.CustomerService;
- import cn.kmust.pagination.pageBean.domain.PageBean;
- /**
- * Web层
- * 继承了我们自己写的BaseServlet类
- * 要求写的方法得与service()相同,
- * 并且.jsp页面必须传递过来一个method参数,如(add、deleter等)
- *
- * @author ZHAOYUQIANG
- *
- */
- public class CustomerServlet extends BaseServlet {
- /*
- * 依赖CustomerService
- */
- private CustomerService cstmService = new CustomerService();
- /**
- * 客户查询所有
- * 加入了分页功能 : 向页面返回当前页的所有记录, 返回的是一个对象,对象中封装了一个beanList集合
- * 该集合中存放这当前页所有记录
- * @param request
- * @param response
- * @return
- * @throws ServletException
- * @throws IOException
- */
- public String queryAll(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- /*
- * 1. 获取list.jsp页面传递的pc
- * 2. 给定每页记录数ps = 10 。开发者根据客户的需求,认为规定的
- * 3. 使用pc和ps调用sevice方法,得到当前页的PageBean对象(该对象中封装了
- * 当前页的所有记录的集合等)
- * 4. 把PageBean保存到request域中
- * 5. 转发到list.jsp
- *
- */
- int pageCode = getCurrentPage(request);
- int pageSize = 10 ; //每页10记录
- PageBean<Customer> pageBean = cstmService.queryAll(pageCode,pageSize);
- /*
- * 因为与条件查询共用一个list.jsp,所以也需要加url
- */
- pageBean.setUrl(getUrl(request));
- request.setAttribute("pageBean", pageBean);
- return "f:/list.jsp";
- }
- /**
- * 条件查询
- * 具有分页功能,按照条件查询,条件也会被带入分页中
- * @param request
- * @param response
- * @return
- * @throws ServletException
- * @throws IOException
- */
- public String query(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- /*
- * 1. 封装表单数据到Customer对象中
- * 只有一个属性username,是查询的条件critaria
- * 2. 得到当前页码 pageCode
- * 3. 给定pageSize 10
- * 4. 使用pageCode和pageSize以及条件对象,调用service方法得到query,
- * 返回当前页的PageBean对象,内封装了当前页的所有记录集合
- * 5. 把PageBean保存到request域中
- * 6. 转发到list.jsp显示成功信息
- */
- Customer criteria = CommonUtils.toBean(request.getParameterMap(), Customer.class);
- /*
- * 处理GET请求方式编码问题
- * 因为query.jsp表单使用的是get提交方法
- */
- criteria = encoding(criteria);
- int pageCode = getCurrentPage(request);
- int pageSize = 10 ; //每页10记录
- PageBean<Customer> pageBean = cstmService.query(criteria,pageCode,pageSize);
- /*
- * 得到url,保存到pageBean对象中
- */
- pageBean.setUrl(getUrl(request));
- request.setAttribute("pageBean", pageBean);
- return "f:/list.jsp";
- }
- /**
- * 处理GET请求乱码
- * 因为BaseSevlet类中只有处理POST请求的乱码,没有GET请求的乱码处理
- * @param criteria
- * @return
- * @throws UnsupportedEncodingException
- */
- private Customer encoding(Customer criteria) throws UnsupportedEncodingException {
- String username = criteria.getUsername();
- if(username != null && !username.trim().isEmpty()){
- username = new String(username.getBytes("ISO-8859-1"),"utf-8");
- criteria.setUsername(username);
- }
- return criteria;
- }
- /**
- * 获取pageCode(当前页码)
- * 传递到Servlet中的参数都是String类型的,所以需要转换
- * pageCode参数如果不存在,说明是第一次调用,当前页码默认为第一页
- * @param request
- * @return
- */
- private int getCurrentPage(HttpServletRequest request){
- String value = request.getParameter("pageCode");
- if(value == null || value.trim().isEmpty()){
- return 1 ;
- }
- return Integer.parseInt(value);
- }
- /**
- * 截取url
- * 条件查询中需要使用
- * /项目名/Servlet路径?参数字符串
- * @param request
- * @return
- */
- private String getUrl(HttpServletRequest request){
- /*
- * 1. 获取项目名
- * 2. 获取Servlet路径
- * 3. 获取参数列表
- * 这个参数是条件
- */
- String contextPath = request.getContextPath();
- String servletPath = request.getServletPath();
- String queryString = request.getQueryString();
- /*
- * 4. 判断是否包含pageCode参数
- * 如果包含需要剪掉,不要这个参数
- */
- if(queryString.contains("&pageCode")){
- int index = queryString.lastIndexOf("&pageCode");
- queryString = queryString.substring(0,index);
- }
- return contextPath+servletPath+"?"+queryString ;
- }
- }
CustomerServlet
- package cn.kmust.pagination.customer.service;
- import java.sql.SQLException;
- import java.util.List;
- import cn.itcast.jdbc.JdbcUtils;
- import cn.kmust.pagination.customer.dao.CustomerDao;
- import cn.kmust.pagination.customer.domain.Customer;
- import cn.kmust.pagination.pageBean.domain.PageBean;
- /**
- * service 层 处理业务
- * @功能
- * 1. 条件查询
- * 2. 查询 所有用户
- * 3. 查询 所有记录行数
- * @author ZHAOYUQIANG
- *
- */
- public class CustomerService {
- /*
- * 依赖CustomerDao
- */
- CustomerDao cstmDao = new CustomerDao();
- /**
- * 条件查询
- *
- * @param criteria
- * @param pageCode
- * @param pageSize
- * @return
- */
- public PageBean<Customer> query(Customer criteria,int pc,int ps) {
- return cstmDao.query(criteria,pc,ps);
- }
- /**
- * 查询所有客户业务
- * 具有分页功能 : 返回PageBean对象 ,对象中封装了 当前页所有记录的集合
- * @param pc
- * @param ps
- * @return
- */
- public PageBean<Customer> queryAll(int pc,int ps){
- return cstmDao.queryAll(pc,ps);
- }
- }
CustomerService
- package cn.kmust.pagination.customer.dao;
- import java.sql.ResultSet;
- import java.sql.SQLException;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Map;
- import javax.sql.DataSource;
- import org.apache.commons.dbutils.QueryRunner;
- import org.apache.commons.dbutils.ResultSetHandler;
- import org.apache.commons.dbutils.handlers.BeanHandler;
- import org.apache.commons.dbutils.handlers.BeanListHandler;
- import org.apache.commons.dbutils.handlers.MapHandler;
- import org.apache.commons.dbutils.handlers.MapListHandler;
- import org.apache.commons.dbutils.handlers.ScalarHandler;
- import cn.itcast.jdbc.JdbcUtils;
- import cn.itcast.jdbc.TxQueryRunner;
- import cn.kmust.pagination.customer.domain.Customer;
- import cn.kmust.pagination.pageBean.domain.PageBean;
- /**
- *dao层
- * 对数据库的操作
- * @author ZHAOYUQIANG
- *
- */
- public class CustomerDao {
- private QueryRunner qr = new TxQueryRunner();
- /**
- * 对数据库进行查询所有客户操作
- * 具有分页功能 : 返回PageBean对象,该对象封装了当前页的所有记录的集合
- * 当前页的所有记录都放到beanList集合中,然后随当前页码等参数封装到pageBean中返回
- * @return
- */
- public PageBean<Customer> queryAll(int pc,int ps){
- try {
- /*
- * 有关数据库的操作:
- * 准备sql模版
- * 调用QueryRunner的query方法
- */
- /*该方法的任务:
- * 1. 创建PageBean对象
- */
- PageBean<Customer> pageBean = new PageBean<Customer>();
- /*
- * 2. 设置pc和ps,封装到我pageBean对象
- */
- pageBean.setPageCode(pc);
- pageBean.setPageSize(ps);
- /*
- * 3. 查询数据库得到totalRecord(数据库所有记录),封装到我pageBean对象
- */
- String sql = "select count(*) from t_customer";
- Number num = (Number)qr.query(sql,new ScalarHandler() );
- int totalRecord = num.intValue();
- pageBean.setTotalRecord(totalRecord);
- /*
- * 4. 查询数据库得到BeanList(当前页记录的集合),封装到我pageBean对象
- * 当前页到底是第几页,当前页有多少条记录呢?
- * 利用mysql的limit子句, (limit 4,10的意思是从第五行记录开始(包含第五行),查询10行记录)
- * 很明显当前页的是从第(pc-1)*ps行开始,查询ps行记录。
- * 根据limit子句的特点,巧妙的设计查询当前页的数据
- * 用order by 通过客户姓名来排序显示
- */
- sql = "select * from t_customer order by username limit ?,?";
- List<Customer> beanList = qr.query(sql,
- new BeanListHandler<Customer>(Customer.class),(pc-1)*ps,ps);
- pageBean.setBeanList(beanList);
- /*
- * 5. 返回PageBean对象
- */
- return pageBean ;
- } catch (SQLException e) {
- throw new RuntimeException(e);
- }
- }
- /**
- * 条件查询
- * 具有分页功能
- * @param criteria
- * @param pc
- * @param ps
- * @return
- */
- public PageBean<Customer> query(Customer criteria,int pc,int ps) {
- try {
- /*
- * 1. 创建PageBean对象
- * 2. 设置已有属性,pc和ps(pageCode和pageSize)
- * 3. 通过条件查询数据库得到totalRecord
- * 4. 查询数据库,返回beanList(当前页记录的集合)
- */
- PageBean<Customer> pageBean = new PageBean<Customer>();
- pageBean.setPageCode(pc);
- pageBean.setPageSize(ps);
- /*
- * 3. 通过条件查询数据库得到totalRecord
- */
- String sql1 = null;
- String username = criteria.getUsername();
- if(username != null && !username.trim().isEmpty()){
- sql1 = "select count(*) from t_customer where username like ?" ;
- }
- Object[] params1 = {"%"+username+"%"};
- /*
- * 3.3. 得到totalRecord
- */
- Number num = (Number)qr.query(sql1,
- new ScalarHandler(),params1);
- int totalRecord = num.intValue();
- pageBean.setTotalRecord(totalRecord);
- /*
- * 4. 查询数据库,返回beanList(当前页记录的集合)
- * 还是需要拼凑sql语句,并且需要limit子句
- * params中需要给出limit后两个问号对应的值
- *
- */
- String sql2 = "select * from t_customer where username like ? limit ?,?";
- Object[] params = {"%"+username+"%",(pc-1)*ps,ps};
- List<Customer> beanList = qr.query(sql2,
- new BeanListHandler<Customer>(Customer.class),
- params);
- pageBean.setBeanList(beanList);
- return pageBean ;
- } catch (SQLException e) {
- throw new RuntimeException(e);
- }
- }
- }
CustomerDao
@项目download http://files.cnblogs.com/files/zyuqiang/jdbcStudy_Demo5_pagination.rar
《JavaWeb从入门到改行》分页功能的实现的更多相关文章
- tableau入门学习笔记--分页功能
最近在使用tableau来制作报表,对于tableau也是第一次接触并使用,每天学习些新的功能来记录在博客里,给他人方便,也给自己方便 tableau分页功能 很多时候由于工作表过长而出现拖拽条,如果 ...
- 《JavaWeb从入门到改行》过滤器学习笔记
>"; display: block; height: 0; clear: both; visibility: hidden; } #sitemap, #sitemap ul{disp ...
- 《JavaWeb从入门到改行》很好的复习资料: SQL语句到底怎么写 ?
本文用到的数据库如下: CREATE DATABASE exam; /创建部门表/ CREATE TABLE dept( deptno INT PRIMARY KEY, dname ), loc ) ...
- 《JavaWeb从入门到改行》JSP+EL+JSTL大杂烩汤
title: Servlet之JSP tags: [] notebook: javaWEB --- JSP是什么 ? JSP就是Servlet,全名是"JavaServer Pages&qu ...
- 《JavaWeb从入门到改行》那些年一起学习的Servlet
目录 获取ServletContext : ServletContext接口中的一些方法 application域存取数据功能 代码演示: application域获取项目文件路径 代码演示: API ...
- 《JavaWeb从入门到改行》JDBC经典秘方QueryRunner
目录: 基础篇_功能各自回顾 JDBC基础代码回顾(使用JdbcUtils工具简化) c3p0数据库连接池的使用(使用JdbcUtils工具简化) 大数据的插入(使用c3p0+JdbcUtils工具简 ...
- 《JavaWeb从入门到改行》fileupload,没毛病
目录: » fileupload API > 文件上传的要求 > fileupload组件 » 上传细节的代码演示 » 项目案例-上传头像并显示 fileupload API 文 ...
- 《JavaWeb从入门到改行》注册时向指定邮箱发送邮件激活
javaMail API javaMail是SUN公司提供的针对邮件的API . 两个jar包 mail.jar 和 activation.jar java mail中主要类:javax.mail. ...
- 《JavaWeb从入门到改行》关于BaseServlet那些事
@为什么需要BaseServlet? 我们知道一个POST或者GET提交对应着一个Servlet, 无数的提交会让Servlet页面增加,我们希望一个Servlet就能处理很多提交的请求. @Bas ...
随机推荐
- 链式二叉树的实现(Java)
定义树节点: package 链式二叉树; public class TreeNode { private Object data; private TreeNode left; private Tr ...
- POJ 2192
#include <iostream> #include <string> #define MAXN 500 using namespace std; bool dp[MAXN ...
- 架构师养成记--32.Redis高级(安全 主从复制)
Redis高级命令及特性 keys * 返回满足的所有键值(*表示模糊匹配) exists 是否存在指定的key(返回1表示存在,0表示不存在) expire 设置某个key的过期时间,使用ttl查看 ...
- js 移动端获取当前用户的经纬度
一.HTML5 geolocation的属性 if(navigator.geolocation){ navigator.geolocation.getCurrentPosition(onSuccess ...
- [Re:从零开始的分布式] 0.x——Reids实现分布式锁
上节提到了,分布式锁通常应满足如下要求,互斥性.高可用.高效率.可重入.锁失效这五个基本原则.由于Redis自身“快”的特点,所以高效率可以看作满足. 下文在单机情况下与多机情况下,对利用Redis实 ...
- OS X获取process.env.NODE_ENV出错
原来项目是其它小组在维护,现在我们需要维护部分功能,把项目带到OS X上运行发现 webpack.config.js获取process.env.NODE_ENV变量出错 解决: 根据电脑操作系统平台类 ...
- [Xamarin] 開啟另外一個Activity 並且帶資料 (转帖)
每隻App是透過許多畫面所組成的,當然可能主畫面之外,都會有許多其他的頁面 再Android 設計中畫面會有配合的Activity 當然在這之前,最好事先了解一下,Android 關於生命週期的規劃 ...
- 【HADR】搭建实战
Summary: 简单的HADR,只用一台虚拟机,两个实例间搭建.工作量不大,一般5分钟左右能够完成. 步骤: 1.设定归档模式 2.使用备份建立standby数据库 3.设定hadr相关的参数 4. ...
- JavaScript引擎理解
JavaScript 虽然给人感觉是一个多线程执行的语言,但是其实JavaScript引擎是伪多线程,是单线程执行的, 浏览器内核:实现允许多个线程异步执行,这些线程在内核制控下相互配合以保持同步.假 ...
- 深度学习(二)BP求解过程和梯度下降
一.原理 重点:明白偏导数含义,是该函数在该点的切线,就是变化率,一定要理解变化率. 1)什么是梯度 梯度本意是一个向量(矢量),当某一函数在某点处沿着该方向的方向导数取得该点处的最大值,即函数在该点 ...