一. 储备知识
在前面的book_manager.jsp页面中,显示所有图书数据都是没有进行条件筛选的。也就是说,数据库在查询图书数据时,效率非常低。再加上如果有成百个人同时访问该网站,数据库的效率则将更加低。所以我们应该设计一个提高效率的显示图书数据的book_manager.jsp页面。
1.1 分析问题
开发中不推荐使用不带条件的查询语句:一次查询所有,mysql执行效率低,用户体验差,使用分页可以解决
技术基础:sql语句采用limit关键字select * from book limit index , size
设计的属性 | 解释 |
---|---|
pageNumber | 页码,用户查询时传入的参数 |
index | 每页数据在数据库中的查询的起始索引值,根据页码和每个分页中的记录条数可以计算得到 (pageNumber - 1)* size |
size | 每页显示数据的记录条数,程序中设置的 |
分页查询的目的是每次查询时只查询一页需要显示的记录封装到集合中
取出book_manager.jsp中需要动态获取的数据来分析Page类应该怎么设计:
1.2 设计思想
管理员选择查询分页数据时,请求可以提交给BookManagerServlet处理[需要提交[pageNumber]
BookManagerServlet: 获取请求参数
- 获取pageNumber
- 获取size(int size = 4;)
BookService: 创建page对象和业务处理
- 创建Page对象,将pageNumber和size设置给page对象
- 通过page.getPageNumber()和page.getSize()可以计算得到page.getIndex()
BookDao: 分页数据库的分页查询(和数据相关的操作需要调用dao并传入封装了两个参数的page对象中,完成数据的继续填充)
- 查询图书的总记录条数并设置给page对象
- 由总记录条数和size可以计算得到page.getTotalPage()
- 根据page对象的index和size属性可以在book表中查询分页需要显示的图书集合data并设置给page对象,返回给service,再返回给Servlet
注意: 分析的时候从上往下(Servlet层->Service层->Dao层),开发的时候从下往上(Dao层->Service层->Servlet层)
1.3 实现步骤
- 创建分页类
Page<T>
- BookDao中提供查询分页数据的方法,
Page<Book> findPage(Page<Book> page);
//page参数包含了pageNumber和size - BookService中提供查询分页的业务方法,
Page<Book> getPage(String pageNumber, int size);
- 测试查询分页步骤的方法
- 在BookManagerServlet中提供分页数据查询请求的方法
- 修改include文件夹中manager_header.jsp中的图书管理超链接地址访问getPage
二. 源码例子
Page.java
package com.atguigu.bookstore.bean;
import java.io.Serializable;
import java.util.List;
/*
*分页类
*/
public class Page<T> implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private List<T> data;//分页需要显示的数据集
private int pageNumber;//当前分页的页码
private int size;//分页需要显示几条记录
private int index;//分页数据查询的起始索引,根据pageNumber和size计算得到
private int totalCount;//数据的总记录条数
private int totalPage;//总页码,根据totalCount和size计算得到
private String path;//分页访问的url路径
public Page() {
super();
// TODO Auto-generated constructor stub
}
public List<T> getData() {
return data;
}
public void setData(List<T> data) {
this.data = data;
}
public int getPageNumber() {
if(pageNumber < 1) {
return 1;
}else if(pageNumber > getTotalPage()) {
return getTotalPage();
}
return pageNumber;
}
public void setPageNumber(int pageNumber) {
this.pageNumber = pageNumber;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public int getIndex() {
return (getPageNumber()-1)*getSize();
}
public void setIndex(int index) {
this.index = index;
}
public int getTotalCount() {
return totalCount;
}
public void setTotalCount(int totalCount) {
this.totalCount = totalCount;
}
/**
* totalPage totalCount size
* 10/4+1 10 4
* 10/ 10 5
* 10/20+1 10 20
* @return
*/
public int getTotalPage() {
if(getTotalCount()%getSize()==0) {
totalPage = getTotalCount()/getSize();
}else {
totalPage = getTotalCount()/getSize()+1;
}
return totalPage;
}
// public void setTotalPage(int totalPage) {
// this.totalPage = totalPage;
// }
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
@Override
public String toString() {
return "Page [data=" + data + ", pageNumber=" + pageNumber + ", size=" + size + ", index=" + index
+ ", totalCount=" + totalCount + ", totalPage=" + totalPage + ", path=" + path + "]";
}
}
BookDaoImpl.java
package com.atguigu.bookstore.dao.impl;
import java.util.List;
import com.atguigu.bookstore.bean.Book;
import com.atguigu.bookstore.bean.Page;
import com.atguigu.bookstore.dao.BaseDao;
import com.atguigu.bookstore.dao.BookDao;
public class BookDaoImpl extends BaseDao implements BookDao{
@Override
public Page<Book> findPage(Page<Book> page) {
// TODO Auto-generated method stub
//目的是为了查询分页需要的数据库数据并设置给page对象
//1.totalCount
String countSql = "select count(*) from book";
int count = (int) getCount(countSql);
page.setTotalCount(count);
//2.data 分页数据集合
String sql = "select id, title, author, price, sales, stock, img_path imgPath"
+ " from book limit ?, ?";
List<Book> data = getBeanList(Book.class, sql, page.getIndex(), page.getSize());
//3.将查询到的data集合设置给page对象
page.setData(data);
//4.返回封装完数据的page对象
return page;
}
}
BookService.java
package com.atguigu.bookstore.service.impl;
import java.util.List;
import com.atguigu.bookstore.bean.Book;
import com.atguigu.bookstore.bean.Page;
import com.atguigu.bookstore.dao.BookDao;
import com.atguigu.bookstore.dao.impl.BookDaoImpl;
import com.atguigu.bookstore.service.BookService;
public class BookServiceImpl implements BookService{
//Service层与数据交互必须通过Dao层实现
private BookDao dao = new BookDaoImpl();
@Override
public Page<Book> getPage(String pageNumber, int size) {
//1.创建分页对象用来携带数据参数
Page<Book> page = new Page<Book>();
//类型转换 由于页码是由用户传入的,有可能不是一个正常的数字类型的字符串,可能有数字转换异常
int number = 1;//设置默认第一页
try {
number = Integer.parseInt(pageNumber);
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//2.将数据设置给page对象
page.setPageNumber(number);
page.setSize(size);
//3.调用dao查询分页数据库的相关数据并设置返回
Page<Book> findPage = dao.findPage(page);
return findPage;
}
}