分页查询
看这里 , 我们先闲聊下吧 , 如果一张表里面有1000条数据 , 你一眼看去会不会很烦呢 ? 会就对啦 , 那就把表分成100份 , 每份10条 , 这样子看是不是舒服点了嘞 . 好 , 那接下来 , 我们就进入 分页查询 .
![](https://img.haomeiwen.com/i23388588/e7a1adc257c4fa30.jpg)
1.分页查询
则是在页面上将本来很多的数据分段显示,每页显示用户自定义的行数。可提高用户体验度,同时减少一次性加载,内存溢出风险。
1.1分页设计 (快速入门).
一般 有两部分组成 :
①. 当前页的结果集数据,比如这一页有哪些商品信息。
②. 分页条信息,比如包含【首页】【上页】【下页】【末页】等
![](https://img.haomeiwen.com/i23388588/de63afdde149f11b.png)
看上图 , 分析 :
我们需要的数据是那些 :
-
当前页货品信息:
- 1.list/result (当前页面集)
-
分页条信息
-
beginPage = 1 首页
-
prevPage 上一页
-
nextPage 下一页
-
totalPage 总页数/末页
-
rows/totalCount 总条数
-
currentPage 当前页
-
pageSize 每页显示多少条数据 当前页的数据
1.2 分页需要依赖的变量
两输 , 两查 , 三计算
需要用户传入的数据:
int currentPage = 1 : 当前页,跳转到第几页
int pageSize = 10 : 每页最多多少条数据
需要两条 SQL 查询的数据
第一条SQL:查询符合条件的结果总数(totalCount/rows)
SELECT COUNT(*) FROM 表名 [WHERE 条件]
第二条SQL:查询符合条件的结果集(result)
SELECT * FROM 表名 [WHERE **条件****] LIMIT ?,?
第一个? : 从哪一个索引的数据开始截取(从0开始) beginIndex = (currentPage - 1) *
pageSize
第二个? : pageSize 每页多少条数据
int totalCount : 数据总条数
List result/list : 每一页的结果集数据
程序猿手动计算
int prevPage : 上一页
int totalPage : 总页数/末页
int nextPage : 下一页
int totalPage = totalCount % pageSize == 0 ? totalCount / pageSize : totalCount / pageSize + 1; (优先计算)
int prevPage = currentPage >1 ? currentPage - 1 : 1;
int nextPage = currentPage <totalPage ? currentPage + 1 : totalPage;
需要的数据这么多 , 那我们把它封装起来吧 , 这样显得我们更优雅 . 到时候, 共享数据就直接可以共享个对象就得嘞! pageResult
@Getter
public class PageResult {
// 2 输 2 查 3 计算
//用户输入 1. 当前页 2.每页显示多少条页数
private int currentPage;//当前页
private int pageSize;//每页显示条数
// sql : 查询 每页总条数 每页结果集
private int totalCount;
private List listData;
//计算 上一页 下一页 末页
private int prevPage; //上一页
private int nextPage;//下一页
private int totalPage;//末页
//自定义带参构造器
public PageResult(int currentPage, int pageSize, int totalCount, List listData) {
this.currentPage = currentPage;
this.pageSize = pageSize;
this.totalCount = totalCount;
this.listData = listData;
this.prevPage=currentPage>1?currentPage-1:1;
this.totalPage=totalCount%pageSize==0?totalCount/pageSize:(totalCount/pageSize)+1;
this.nextPage=currentPage<totalPage?currentPage+1:totalPage;
}
}
DAO 方法设计
DAO 增加两个方法,分别用于查询结果总数和结果集。
public interface ICustomerDAO {
//--------分页查询
int queryForCount(QueryObject qo);
//总条数
List<?>queryForList(QueryObject qo);
//页面集
}
DAO 实现
准备工作: 定义 QueryObject 类,用于封装分页查询前台用户传入数据,存放于 query 包中
public class CustomerDAOImpl implements ICustomerDAO {
//--------------------------- 分页查询 --------------------
@Override
public int queryForCount(QueryObject qo) {
SqlSession sqlsession = MyBatisUtil.getSqlsession();
int totalCount = sqlsession.selectOne("cn.wolfcode.cmis.mapper.CustomerMapper.queryForCount", qo);
sqlsession.close();
return totalCount;
}
@Override
public List<?> queryForList(QueryObject qo) {
SqlSession sqlsession = MyBatisUtil.getSqlsession();
List<Customer> lsit = sqlsession.selectList("cn.wolfcode.cmis.mapper.CustomerMapper.queryForList", qo);
sqlsession.close();
return lsit;
}
}
Mapper.xml 文件
<select id="queryForCount" resultType="int">
SELECT count(*) FROM t_customer
</select>
<select id="queryForList" resultType="customer">
SELECT * FROM t_customer limit #{beginIndex} , #{pageSize}
</select>
QueryObject
@Getter
@Setter
public class QueryObject {
//用户传入的数据
private int currentPage = 1;
private int pageSize = 3;
public int getBeginIndex() {
return (currentPage - 1) * pageSize;
}
}
测试 :
public class CustomerDAOImplTest {
ICustomerDAO dao=new CustomerDAOImpl();
//-------------------分页
@Test
public void queryForCount() {
QueryObject qo = new QueryObject();
int i = dao.queryForCount(qo);
System.out.println(i);
}
@Test
public void queryForList() {
QueryObject qo = new QueryObject();
List<?> queryForList = dao.queryForList(qo);
for (Object customer:queryForList) {
System.out.println(customer);
}
System.out.println(queryForList);
}
2 控制台版本分页实现
public class CustomerServiceImpl implements ICustomerService{
@Override
public PageResult query(QueryObject qo) {
//这里获取到了 用户传过来的两个数据 , 那就 可以获取 两个sql 的返回数据
ICustomerDAO dao=new CustomerDAOImpl();
//获取到sql 结果集
List<?> list = dao.queryForList(qo);
//获取到sql 总条数
int count = dao.queryForCount(qo);
if(count==0){
return new PageResult(qo.getCurrentPage(),qo.getPageSize(), 0, new ArrayList());
}
return new PageResult(qo.getCurrentPage(),qo.getPageSize(), count, list);
}
}
测试:
public class CustomerServiceImplTest {
@Test
public void query() {
QueryObject qo = new QueryObject();
qo.setCurrentPage(2);
ICustomerService service=new CustomerServiceImpl();
PageResult query = service.query(qo);
System.out.println("当前页 : "+query.getCurrentPage());
System.out.println("页面集 : "+query.getListData());
System.out.println("下一页 :"+query.getNextPage());
System.out.println("每页显示多少 :"+query.getPageSize());
System.out.println("上一页 :"+query.getPrevPage());
System.out.println("总条数 :"+query.getTotalCount());
System.out.println("总页数 :"+query.getTotalPage());
}
}
Servlet
@WebServlet("/cus")
public class CustomerServlet extends HttpServlet {
//ICustomerDAO dao = new CustomerDAOImpl();
ICustomerService service = new CustomerServiceImpl();
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取请求参数 封装成 对象
QueryObject qo = new QueryObject();
String strPagesize = req.getParameter("pagesize");
if (StringUtil.hasLength(strPagesize)) {
Integer pagesize = Integer.valueOf(strPagesize);
qo.setPageSize(pagesize);
}
String strCurrentPage = req.getParameter("currentPage");
if (StringUtil.hasLength(strCurrentPage)) {
Integer currentPage = Integer.valueOf(strCurrentPage);
qo.setCurrentPage(currentPage);
}
//2.调用业务方法
PageResult result = service.query(qo);
//3.共享---跳转
req.setAttribute("result", result);
req.getRequestDispatcher("list.jsp").forward(req, resp);
}
}
list . jsp
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>查询页面</title>
</head>
<script>
function onchangeSize() {
var formEle = document.getElementById("submitForm");
formEle.submit();
}
</script>
<body>
<a href="/cus?cmd=input">添加</a>
<form method="post" name="submitForm" action="/cus">
<table border="1" cellspacing="0" cellpadding="0" width="80%">
<tr>
<th>序号</th>
<th>名字</th>
<th>年龄</th>
<th>消费</th>
</tr>
<c:forEach items="${result.listData}" var="cus" varStatus="vs">
<tr>
<td>${vs.count}</td>
<td>${cus.name}</td>
<td>${cus.age}</td>
<td>${cus.consumption}</td>
</tr>
</c:forEach>
<tr align="center">
<td colspan="4"><a href="/cus?currentPage=1">首页</a>
<a href="/cus?currentPage=${result.prevPage}">上一页</a>
<a href="/cus?currentPage=${result.nextPage}">下一页</a>
<a href="/cus?currentPage=${result.totalPage}">尾页</a>
当前${result.currentPage}页/${result.totalPage}页
跳转到<input type="number" name="currentPage" style="width:60px" onchange="onchangeSize()"
value="${result.currentPage}"> 页
每页显示
<select name="pagesize" onchange="onchangeSize()">
<option value="3" ${result.pageSize==3 ? 'selected':''}> 3</option>
<option value="5" ${result.pageSize==5 ? 'selected':''}> 5</option>
<option value="8" ${result.pageSize==8 ? 'selected':''}> 8</option>
</select>条数据
</td>
</tr>
</table>
</form>
</body>
</html>
网友评论