mysql高级查询~分页查询
高级查询~分页查询
一、分页设计原理与设计:
1、分页设计
(1)逻辑分页(假分页/内存分页):
一次性
把数据库某张表中所有数据
都查询出来,存放到一个List集合中
,每次翻页的时候,只需要从内存(List)中去获取指定的条数即可
第一页:索引从0~9的元素
第二页:索引从10~19的元素
-
优点:操作简单,翻页比较快。
-
缺点:第一次查询比较慢,
数据过多,可能造成内存溢出
。
(2) 物理分页(真分页/数据库分页)【推荐
】,比如mysql中使用LIMIT
,Oracle使用子查询
每次翻页都从数据库中查询指定的条数。
第一页:从数据库中查询第一个10条数据
第二页:从数据库中查询第二个10条数据
- 优点:若数据过多,不会造成内存溢出的情况
- 缺点:每次翻页都需要从数据库中查询,翻页比较慢
2、分页的原理:(两条sql查询语句)
① 第一条sql:查询符合条件的结果总数
(totalCount):
SELECT COUNT(id) FROM 表名 [WHERE 条件];
② 分页查询(LIMIT) 符合条件的结果集
(resultSet):
SELECT COUNT(id) FROM 表名 [WHERE 条件] LIMIT beginIndex, pageSize;
- beginIndex 索引是从0开始的,从哪一条数据开始截取
beginIndex = (currentPage - 1) * pageSize;
- pageSize 每次截取多少条数据
(1) 需要用户传入的数据:当前页数 currentPage
(默认值是1) 每页最多展示数据 pageSize
(2) 程序员计算(考虑代码的健壮性—进行分析判断):
- 首页(即第一页,默认值是1):beginPage = 1;
- 上一页:prevPage = currentPage - 1 >= 1 ? currentPage - 1 : 1;
- 下一页:nextPage = currentPage + 1 <= totalPage ? currentPage + 1 : totalPage;
- 总页数:totalPage = totalCount % pageSize == 0 ? totalCount/pageSize : totalCount/pageSize + 1;
3、(分页查询)临散数据的封装:
(1)临散的数据如下:
(2)解决:把分页结果数据存储到分页结果对象
(PageResult/PageList)
//分页的结果对象
public class PageResult<T> {
//两条sql语句【分页查询LIMIT、结果集总数COUNT】
private List<T> listData;//分页查询的结果集数据(分页LIMITsql查询)
private Integer totalCount;//结果总条数(COUNT的sql查询)
//用户输入的当前页、每页条数
private Integer currentPage = 1;
private Integer pageSize = 4;
//计算得出
private Integer beginPage = 1;//首页(第一页)
private Integer prevPage;//上页
private Integer nextPage;//下页
private Integer totalPage;//末页(总页)
}
(3)封装之后的servlet和jsp对比:
4、增加分页查询的思路:
4-1、后台实现【DAO层新增分页查询结果的接口】
(1) 封装了分页查询看到的
所有数据(比较临散)PageResult对象
(2) DAO层增加分页查询方法(返回值是分页查询对象PageResult,传入用户输入的参数【currentPage、pageSize】) 和 DAOImpl中增加具体实现
(3) 编写测试新增分页查询的代码
4-2、前台实现
(1)从界面(jsp
)开始设计:添加上分页的界面设计(jsp的数据还没使用${}):
(2) 书写(servlet
)来处理分页查询请求的PageServlet(servlet中调用的业务方法的参数应该从用户输入传递过来【接收请求】)
//先写死数据共享到jsp,来完成jsp界面的${}数据
PageResult<Teacher> pageResult = teacherDAO.query(2, 5);
req.setAttribute("pageResult", pageResult);
// 3、控制页面跳转[1、对应的jsp在WEB-INF里,2、需要共享数据过去]
req.getRequestDispatcher("/WEB-INF/views/teacher/teacher_list.jsp").forward(req, resp);
(3) 先完成jsp的数据(从servlet共享传递过来的)—使用${}:
<%-- 分页查询 --%>
<tr>
<td colspan="8" align="center">
<a href="/page?currentPage=1">首页</a>
<a href="/page?curentPage=${pageResult.prevPage}">上页</a>
<a href="/page?curentPage=${pageResult.nextPage}">下页</a>
<a href="/page?curentPage=${pageResult.totalPage}">末页</a>
当前第${pageResult.currentPage}页/${pageResult.totalPage}页,一共${pageResult.totalCount}条数据
</td>
</tr>
(4)servlet中调用的业务方法参数应该从用户输入传递过来[jsp界面输入传递过来的数据,即接收请求参数]:
//接收请求参数(接收从jsp中输入传递过来的数据)
Integer currentPage = 1;
String sCurrentPage = req.getParameter("currentPage");
if(StringUtils.isNotBlank(sCurrentPage)) {
currentPage = Integer.valueOf(sCurrentPage);
System.out.println(currentPage);
}
//接收参数currentPage(pageSize同理)
PageResult<Teacher> pageResult = teacherDAO.query(currentPage, 5);