分页功能的实现——Jdbc && JSP
@目录
项目案例: 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
分页功能的实现——Jdbc && JSP的更多相关文章
- JDBC使用数据库来完成分页功能
本篇讲诉如何在页面中通过操作数据库来完成数据显示的分页功能.当一个操作数据库进行查询的语句返回的结果集内容如果过多,那么内存极有可能溢出,所以在大数据的情况下分页是必须的.当然分页能通过很多种方式来实 ...
- jsp、js分页功能的简单总结
一.概述 首先,我们要明确为何需要分页技术,主要原因有以下: 1.分页可以提高客户体验度,适当地选择合适的数据条数,让页面显得更有条理,使得用户体验感良好,避免过多数据的冗余. 2.提高性能的需要.分 ...
- 基于SSM框架的简易的分页功能——包含maven项目的搭建
新人第一次发帖,有什么不对的地方请多多指教~~ 分页这个功能经常会被使用到,我之前学习的时候找了很多资源,可都看不懂(笨死算了),最后还是在朋友帮助下做出了这个分页.我现在把我所能想到的知识 做了一个 ...
- 《JavaWeb从入门到改行》分页功能的实现
@目录 什么是分页 ? 两个子模块功能的问题分析 和 解决方案 有条件查和无条件查询的影响 和 解决方案 项目案例: mysql + commons-dbutils+itcast-tools+Base ...
- 【jQuery 分页】jQuery分页功能的实现
自写的jQuery实现分页功能的分页组件: 功能效果如下: 分页组件就是上图中的三部分, 分别放在表格上部 和下部 . 其中, 1>>>页面的代码如下: product.jsp 其 ...
- spring和mybatis集成,自动生成model、mapper,增加mybatis分页功能
软件简介 Spring是一个流行的控制反转(IoC)和面向切面(AOP)的容器框架,在java webapp开发中使用广泛.http://projects.spring.io/spring-frame ...
- aspnetpager+repeater+oracle实现分页功能
一.设计原理阐述 数据查询分页,这个功能相信大家都很熟悉,通过数据库或其它数据源进行查询操作后,将获得的数据显示到界面上,但是由于数据量太大,不能一次性完全的显示出来,就有了数据分页的需求.这个需求在 ...
- MyBatis 拦截器 (实现分页功能)
由于业务关系 巴拉巴拉巴拉 好吧 简单来说就是 原来的业务是 需要再实现类里写 selectCount 和selectPage两个方法才能实现分页功能 现在想要达到效果是 只通过一个方法就可以实现 也 ...
- hibernate和struts2实现分页功能
1.DAO层接口的设计,定义一个PersonDAO接口,里面声明了两个方法: public interface PersonDAO { public List<Person> queryB ...
随机推荐
- Unexpected end of input 和 Unexpected token var 和 Unexpected token ;
在写jsp的时候使用的一段代码一直调试,出现Unexpected token ; 错误. 所以最后把代码各种精简,得到了如下的测试示例代码 <% String aaa="123&quo ...
- python爬虫 模拟登陆校园网-初级
最近跟同学学习爬虫的时候看到网上有个帖子,好像是山大校园网不稳定,用py做了个模拟登陆很有趣,于是我走上了一条不归路..... 先上一张校园网截图 首先弄清一下模拟登陆的原理: 1:服务器判定浏览器登 ...
- nginx之 nginx-1.9.7 + tomcat-8.5.15 反向代理+应用负载均衡 安装配置
环境说明:nginx 反向代理服务器 ip 为: 10.219.24.26tomcat1 应用服务器 ip 为: 10.219.24.21tomcat3 应用服务器 ip 为: 10.219.24.2 ...
- SQL之删除触发器
比如要删除的触发器名字叫dbo.test_trigger. 先判断这个触发器是否存在,判断存在后删除 if exists (select * from sysobjects where name = ...
- java 类变量的初始化
有代码如下:class Price{ final static Price INSTANCE = NEW Price(2.8); static double initPrice = 20; ...
- VR虚拟现实技术在教育领域的前景展望
VR虚拟现实技术在教育领域的前景展望 VR虚拟现实技术能迅速火起来,是基于它突破了人们对三维空间在时间与地域上的感知限制,以及市场需求愿景的升级.此技术可广泛地应用到城市规划.室内设计.工业仿真.古迹 ...
- java中方法总结(每周更新)
1.URLEncoder.encode(username,"utf-8")将"utf-8"编码的username先解码,然后再采用URL编码 2.URLDeco ...
- PHP基础入门(四)---PHP数组实用基础知识
PHP数组 数组是特殊的变量,它可以同时保存一个以上的值. ***关键词:数组基础.数组遍历.超全局数组.数组功能.数组函数. 下面来和大家分享一下有关PHP的数组基础知识,希望对你PHP的学习有所帮 ...
- Linux下Shadow socks的安装和配置
实在受不了在Windows下编程,所以自己就安装了一个Ubutun,公司用的FQ软件shadowsocks在Windows上用起来很简单很爽,但是在Ubutun上的安装和配置就没那么简单了,写下这篇文 ...
- 浅谈WEB编辑器——HBuilder
我自己用过的WEB编辑器有两种:HBuilder和Dreamweaver.这两种编辑器各有各的特点,但是相对来说,我倾向于前者:后者给我的感觉就是功能繁杂,运行起来慢,而且编码的便捷度不高,时不时需要 ...