1 分页
1.1 分页和页码思路
* 已知
* 每页条数:pageSize
* 总条数:totalRecord
* 请求当前页:pageNum
* 算出来
* 总页数:totalPage
* 当可以整除的时候:totalPage=totalRecord/pageSize
* 当不可以整除的时候:totalPage=totalRecord/pageSize+1
*起始坐标:startIndex
mysql:
SELECT * FROM emp LIMIT 0,3;
SELECT * FROM emp LIMIT 3,3;
SELECT * FROM emp LIMIT 6,3;
SELECT * FROM emp LIMIT 9,3;
SELECT * FROM emp LIMIT 12,3;
n=pageNum-1(pageNum从1开始)
SELECT * FROM emp LIMIT n*pageSize,pageSize;
oracle:
select * from (select rownum rn ,t.* from tt12 t where rownum<8) where rn>4;
startIndex=(pageNum-1)*pageSize
* 分页的页数
* start
* end
* 假如也是1,2,3,4,5,start为1,end为5
* 思路
* 假如总页数小于等于5,start=1,end=totalPage
* 假如总页数大于5,start=pageNum-2,end=pageNum+2
* 假如pageNum=8,start=6,end=10
* 边界判断
* 当start小于等于0:start=1,end=5
* 当end大于等于totalPage:start= totalPage-5,end=totalPage
* 集合
* List<T>
* dao层
* int findCount();
* List<T> findTByPageNum(int startIndex,int pageSize);
* 服务层
* 一些校验和业务相关
* 调用dao层代码获取List<T>
* 控制层(Serlvet)
* 获取传递过参数(pageNum)
* List<T> findTByPageNum(int startIndex,int pageSize);
* 展示层
* 假如当前页为第一页,就没有上一页,显示下一页
* 假如当前不是第一页,页不是最后一页,显示上一页,显示下一页
* 假如当前页是最后一页,就没有下页,显示上一页
1.2 开发步骤
1.2.1 数据库表搭建
1.2.2 数据库驱动,数据库连接池,DbUtils,JSTLjar引入
1.2.3 数据库连接池(c3p0)配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!-- c3p0-config.xml必须位于类路径下面 private static ComboPooledDataSource ds; static{
try { ds = new ComboPooledDataSource("MySQL"); } catch (Exception e) { throw
new ExceptionInInitializerError(e); } } -->
<c3p0-config>
<!-- C3P0的缺省(默认)配置, 如果在代码中“ComboPooledDataSource ds = new ComboPooledDataSource();”这样写就表示使用的是C3P0的缺省(默认)配置信息来创建数据源 -->
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/etc0102</property>
<property name="user">root</property>
<property name="password">root</property>
<property name="acquireIncrement">5</property>
<property name="initialPoolSize">10</property>
<property name="minPoolSize">5</property>
<property name="maxPoolSize">20</property>
</default-config>
<!-- C3P0的命名配置, 如果在代码中“ComboPooledDataSource ds = new ComboPooledDataSource("MySQL");”这样写就表示使用的是name是MySQL的配置信息来创建数据源 -->
<named-config name="MySQL">
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/etc0102</property>
<property name="user">root</property>
<property name="password">root</property>
<property name="acquireIncrement">5</property>
<property name="initialPoolSize">10</property>
<property name="minPoolSize">5</property>
<property name="maxPoolSize">20</property>
</named-config>
</c3p0-config>
public class JDBCUtils_C3P0 {
private static ComboPooledDataSource ds = null;
// 在静态代码块中创建数据库连接池
static {
try {
ds = new ComboPooledDataSource("MySQL");
} catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
public static ComboPooledDataSource getDataSource() {
return ds;
}
public static Connection getConnection() throws SQLException {
// 从数据源中获取数据库连接
return ds.getConnection();
}
/**
* 关闭的方法 Statement:通过定义父接口,如果传入的参数是Preparestatement也通用
*/
public static void close(Connection conn, Statement stmt, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {// 如果连接不为空
try {
if (!conn.isClosed()) {// 如果连接没有关闭
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
1.2.5 账户实体编写
public class Account {
private int id;
private String name;
private double money;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
@Override
public String toString() {
return "Account [id=" + id + ", name=" + name + ", money=" + money + "]";
}
}
public class AccountDao {
// 查询所有记录
public int findCount() throws SQLException {
QueryRunner queryRunner = new QueryRunner(JDBCUtils_C3P0.getDataSource());
String sql = "select count(*) from account";
Long count = queryRunner.query(sql, new ScalarHandler<Long>());
return count.intValue();
}
// 根据下标和每页条数,查询账户列表
public List<Account> findAcountByPageNum(int startIndex, int pageSize) throws SQLException {
QueryRunner queryRunner = new QueryRunner(JDBCUtils_C3P0.getDataSource());
String sql="select * from account limit ?,?";
List<Account> accounts = queryRunner.query(sql, new BeanListHandler<Account>(Account.class), startIndex,pageSize);
return accounts;
}
}
Dao层单元测试
@Test
public void test1() throws SQLException {
AccountDao accountDao=new AccountDao();
int count = accountDao.findCount();
System.out.println(count);
}
@Test
public void test2() throws SQLException {
AccountDao accountDao=new AccountDao();
List<Account> accounts = accountDao.findAcountByPageNum(0, 10);
System.out.println(accounts);
}
分页PageBean的编写
public class PageBean<T> {
// 已知
// 每页条数:pageSize
private int pageSize;
// 总条数:totalRecord
private int totalRecord;
// 请求当前页:pageNum
private int pageNum;
// 集合
private List<T> list;
// 计算出来
// 总页数:totalPage
private int totalPage;
// 起始坐标:startIndex
private int startIndex;
// 当前start,end,假如分页1,2,3,4,5,start=1,end=5
private int start;
private int end;
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getTotalRecord() {
return totalRecord;
}
public void setTotalRecord(int totalRecord) {
this.totalRecord = totalRecord;
}
public int getPageNum() {
return pageNum;
}
public void setPageNum(int pageNum) {
this.pageNum = pageNum;
}
public List<T> getList() {
return list;
}
public void setList(List<T> list) {
this.list = list;
}
public int getTotalPage() {
return totalPage;
}
public int getStartIndex() {
return startIndex;
}
public int getStart() {
return start;
}
public int getEnd() {
return end;
}
// 构建器
public PageBean(int pageSize, int totalRecord, int pageNum) {
super();
this.pageSize = pageSize;
this.totalRecord = totalRecord;
this.pageNum = pageNum;
// * 总页数:totalPage
// * 当可以整除的时候:totalPage=totalRecord/pageSize
// * 当不可以整除的时候:totalPage=totalRecord/pageSize+1
if (totalRecord % pageSize == 0) {// 可以整除的时候
totalPage = totalRecord / pageSize;
} else {
totalPage = totalRecord / pageSize + 1;
}
startIndex = (pageNum - 1) * pageSize;
// * 思路
// * 假如总页数小于等于5,start=1,end=totalPage
// * 假如总页数大于5,start=pageNum-2,end=pageNum+2
// * 假如pageNum=8,start=6,end=10
// * 边界判断
// * 当start小于0:start=1,end=5
// * 当end大于totalPage:start= totalPage-5,end=totalPage
start = 1;
end = 5;
if(totalPage<=5) {
end=totalPage;
}else {
start=pageNum-2;
end=pageNum+2;
if(start<=0) {
start = 1;
end = 5;
}
if(end>=totalPage) {
start=totalPage-5;
end=totalPage;
}
}
}
}
Service的层编写
public class UserService {
public PageBean<Account> findAllAccount(int pageNum, int pageSize) throws SQLException {
AccountDao accountdao = new AccountDao();
int totalRecord = accountdao.findCount();
PageBean<Account> pageBean = new PageBean<Account>(pageSize, totalRecord, pageNum);
int startIndex = pageBean.getStartIndex();
List<Account> accounts = accountdao.findAcountByPageNum(startIndex, pageSize);
pageBean.setList(accounts);
return pageBean;
}
}
Service的层单元测试
@Test
public void test3() throws SQLException {
UserService userService=new UserService();
PageBean<Account> pageBean = userService.findAllAccount(1, 10);
System.out.println(pageBean);
}
Servlet层的编写(控制层)
@WebServlet("/query")
public class QueryAccountByPageServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public QueryAccountByPageServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1 设置编码
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
// 2 获取请求参数
String num = request.getParameter("num");
if(num==null) {
num="1";
}
int pageNum=Integer.parseInt(num);
int pageSize=10;
// 3 查询列表
UserService userService=new UserService();
try {
PageBean<Account> pageBean = userService.findAllAccount(pageNum, pageSize);
// 4 设置到request域中
request.setAttribute("pageBean", pageBean);
// 5 请求转发到列表显示页面
request.getRequestDispatcher("/list.jsp").forward(request, response);
} catch (SQLException e) {
e.printStackTrace();
request.setAttribute("msg", "系统暂时维护,请联系管理员");
request.getRequestDispatcher("/error.jsp").forward(request, response);
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
JSP页面展示(视图层(View))
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
<style type="text/css">
table.gridtable {
font-family: verdana, arial, sans-serif;
font-size: 11px;
color: #333333;
border-width: 1px;
border-color: #666666;
border-collapse: collapse;
}
table.gridtable th {
border-width: 1px;
padding: 8px;
border-style: solid;
border-color: #666666;
background-color: #dedede;
}
table.gridtable td {
border-width: 1px;
padding: 8px;
border-style: solid;
border-color: #666666;
background-color: #ffffff;
}
</style>
</head>
<body>
<h1>列表显示</h1>
<table class="gridtable">
<tr>
<th>id</th>
<th>姓名</th>
<th>金额</th>
</tr>
<c:forEach items="${pageBean.list }" var="account">
<tr>
<td>${account.id }</td>
<td>${account.name }</td>
<td>${account.money }</td>
<tr>
</c:forEach>
<!-- * 假如当前页为第一页,就没有上一页,显示下一页
* 假如当前不是第一页,页不是最后一页,显示上一页,显示下一页
* 假如当前页是最后一页,就没有下页,显示上一页 -->
</table>
<%-- 构建分页导航 --%>
共有${requestScope.pageBean.totalRecord}个员工,共${requestScope.pageBean.totalPage }页,当前为${requestScope.pageBean.pageNum}页
<br />
<a href="${pageContext.request.contextPath}/query?num=1">首页</a>
<%--如果当前页为第一页时,就没有上一页这个超链接显示 --%>
<c:if test="${requestScope.pageBean.pageNum ==1}">
<c:forEach begin="${requestScope.pageBean.start}"
end="${requestScope.pageBean.end}" step="1" var="i">
<c:if test="${requestScope.pageBean.pageNum == i}">
${i}
</c:if>
<c:if test="${requestScope.pageBean.pageNum != i}">
<a href="${pageContext.request.contextPath}/query?num=${i}">${i}</a>
</c:if>
</c:forEach>
<a
href="${pageContext.request.contextPath}/query?num=${requestScope.pageBean.pageNum+1}">下一页</a>
</c:if>
<%--如果当前页不是第一页也不是最后一页,则有上一页和下一页这个超链接显示 --%>
<c:if
test="${requestScope.pageBean.pageNum > 1 && requestScope.pageBean.pageNum < requestScope.pageBean.totalPage}">
<a
href="${pageContext.request.contextPath}/query?num=${requestScope.pageBean.pageNum-1}">上一页</a>
<c:forEach begin="${requestScope.pageBean.start}"
end="${requestScope.pageBean.end}" step="1" var="i">
<c:if test="${requestScope.pageBean.pageNum == i}">
${i}
</c:if>
<c:if test="${requestScope.pageBean.pageNum != i}">
<a href="${pageContext.request.contextPath}/query?num=${i}">${i}</a>
</c:if>
</c:forEach>
<a
href="${pageContext.request.contextPath}/query?num=${requestScope.pageBean.pageNum+1}">下一页</a>
</c:if>
<%-- 如果当前页是最后一页,则只有上一页这个超链接显示,下一页没有 --%>
<c:if
test="${requestScope.pageBean.pageNum == requestScope.pageBean.totalPage}">
<a
href="${pageContext.request.contextPath}/query?num=${requestScope.pageBean.pageNum-1}">上一页</a>
<c:forEach begin="${requestScope.pageBean.start}"
end="${requestScope.pageBean.end}" step="1" var="i">
<c:if test="${requestScope.pageBean.pageNum == i}">
${i}
</c:if>
<c:if test="${requestScope.pageBean.pageNum != i}">
<a href="${pageContext.request.contextPath}/query?num=${i}">${i}</a>
</c:if>
</c:forEach>
</c:if>
<%--尾页 --%>
<a
href="${pageContext.request.contextPath}/query?num=${requestScope.pageBean.totalPage}">尾页</a>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body>
<h1 style="color: red">
${msg }
</h1>
</body>
</html>