分页功能的实现:
- 物理分页:一次只查指定条记录,点击下一页,再去查询后指定条.使用SQL语句进行控制的分页.
- 缺点:经常需要和数据库交互.
- 优点:数据量特别大,不会导致内存的溢出.
- 逻辑分页:一次性将所有数据全都查询出来,根据需要进行截取.List集合进行控制. subList();
- 缺点:数据量如果特别大,容易导致内存溢出.
- 优点:与数据库交互次数少.
实现详解
不同的数据库对分页的语句也是不一样的:
- MYSQL进行分页: 使用limit关键字.
- select * from xxx where .. Group by … Having … Order by … limit a,b; – a:从哪开始 b:查询的记录数.
- 根据页数计算 limit后面的两个参数:
- currPage begin pageSize
1 0 10
2 10 10
3 20 10 - begin = (currPage - 1) * pageSize;
- currPage begin pageSize
- 参数的传递:
- 前台—>后台:currPage
- 后台—>前台:currPage,totalPage(总页数),totalCount(总记录数),pageSize,List集合.
- 使用JavaBean封装参数:
- 后台—>前台:传递一个JavaBean就可以.
- Oracle进行分页: 使用SQL语句嵌套.
- SQL Server数据库进行分页: 使用 top 关键字.
- MYSQL进行分页: 使用limit关键字.
在首页上添加一个分页查询的链接:
关键代码实现
//service层处理逻辑,JavaBean就不写了
public PageBean findPage(int currPage) throws SQLException {
PageBean pageBean = new PageBean();
// 设置当前页数
pageBean.setCurrPage(currPage);
//设置每页显示的记录数
int pageSize=10;
pageBean.setPageSize(pageSize);
//设置总的记录数
ProductDAO productDAO = new ProductDAO();
int count = productDAO.findCount();
pageBean.setTotalCount(count);
//设置总的页数
Double pageNum = Math.ceil(count/pageSize);
pageBean.setTotalPage(pageNum.intValue());
//每页显示的记录集合boub
int begin = (currPage-1)*pageSize;
List<Product> list = productDAO.findByPage(begin,pageSize);
pageBean.setList(list);
return pageBean;
}
//DAO层实现:
public List<Product> findByPage(int begin, int pageSize) throws SQLException {
//创建查询对象
QueryRunner queryRunner = new QueryRunner(JDBCUtils.getDataSource());
String sql = "select * from product order by pdate limit ?,?";
List<Product> list = queryRunner.query(sql, new BeanListHandler<Product>(Product.class),begin,pageSize);
return list;
}
public int findCount() throws SQLException {
//创建查询对象
QueryRunner queryRunner = new QueryRunner(JDBCUtils.getDataSource());
//查询总的记录数
String sql = "select count(*) from product ";
Long count = (Long) queryRunner.query(sql, new ScalarHandler());
return count.intValue();
}
//servlet层的实现
//post提交乱码处理问题
request.setCharacterEncoding("utf-8");
// 接收数据
Product product = new Product();
Map<String, String[]> map = request.getParameterMap();
//封装数据
BeanUtils.populate(product, map);
//调用业务层处理数据
ProductService service = new ProductService();
List<Product> list = service.findproduct(product);
//响应浏览器
request.setAttribute("lsit", list);
request.getRequestDispatcher("/jsp/product_page.jsp").forward(request, response);
JSP页面的实现:使用jstl,需要导入两个jar包,引入标签库代码实现如下:
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="${ pageContext.request.contextPath }/js/jquery-1.8.3.js"></script>
<script type="text/javascript">
function addPage(){
window.location.href="${ pageContext.request.contextPath }/jsp/addProduct.jsp";
}
function del(pid){
var flag = window.confirm("您确定删除这条记录吗?");
if(flag == true){
window.location.href="${ pageContext.request.contextPath }/ProductDeleteServlet?pid="+pid;
}
}
function delAll(){
document.getElementById("form1").submit();
}
function search(){
// 获得文本框的值:
var pname = document.getElementById("pname").value;
// 获得表单:
document.getElementById("form1").action="${ pageContext.request.contextPath }/ProductSearchServlet";
// 表单提交:
document.getElementById("form1").submit();
}
$(function(){
$("#selectAll").click(function(){
$("input[id='ids']").prop("checked",this.checked);
});
});
</script>
</head>
<body>
<h1>商品的列表页面</h1>
<form id="form1" action="${ pageContext.request.contextPath }/ProductDeleteAllServlet" method="post">
<table border="1" width="800">
<tr>
<td colspan="8">
名称:<input type="text" id="pname" name="pname"><input type="button" value="查询" onclick="search()">
<input type="button" value="添加" onclick="addPage()"/>
<input type="button" value="删除" onclick="delAll()"/>
</td>
</tr>
<tr>
<td>序号</td>
<td><input type="checkbox" id="selectAll" /></td>
<td>商品名称</td>
<td>市场价格</td>
<td>商城价格</td>
<td>是否热门</td>
<td>是否下架</td>
<td>操作</td>
</tr>
<c:forEach var="p" items="${ pageBean.list }" varStatus="status">
<tr>
<td>${ status.count }</td>
<td><input type="checkbox" id="ids" name="ids" value="${ p.pid }"/></td>
<td>${ p.pname }</td>
<td>${ p.market_price }</td>
<td>${ p.shop_price }</td>
<td>
<c:if test="${ p.is_hot == 1 }">
是
</c:if>
<c:if test="${ p.is_hot == 0 }">
否
</c:if>
</td>
<td>
<c:if test="${ p.pflag == 1 }">
已下架
</c:if>
<c:if test="${ p.pflag == 0 }">
未下架
</c:if>
</td>
<td><a href="${ pageContext.request.contextPath }/ProductEditServlet?pid=${p.pid}">修改</a>|<a href="#" onclick="del('${p.pid}')">删除</a></td>
</tr>
</c:forEach>
<tr>
<td colspan="8" align="center">
第${ pageBean.currPage }/${ pageBean.totalPage }页
总记录数:${ pageBean.totalCount } 每页显示的记录数:${ pageBean.pageSize }
<c:if test="${ pageBean.currPage != 1 }">
<a href="${ pageContext.request.contextPath }/ProductFindByPageServlet?currPage=1">[首页]</a>
<a href="${ pageContext.request.contextPath }/ProductFindByPageServlet?currPage=${ pageBean.currPage - 1 }">[上一页]</a>
</c:if>
<c:forEach var="i" begin="1" end="${ pageBean.totalPage }">
<c:if test="${ pageBean.currPage != i }">
<a href="${ pageContext.request.contextPath }/ProductFindByPageServlet?currPage=${i}">${ i }</a>
</c:if>
<c:if test="${ pageBean.currPage == i }">
${ i }
</c:if>
</c:forEach>
<c:if test="${ pageBean.currPage != pageBean.totalPage }">
<a href="${ pageContext.request.contextPath }/ProductFindByPageServlet?currPage=${ pageBean.currPage + 1}">[下一页]</a>
<a href="${ pageContext.request.contextPath }/ProductFindByPageServlet?currPage=${ pageBean.totalPage }">[尾页]</a>
</c:if>
</td>
</tr>
</table>
</form>
</body>