分页查询
分页查询用于在处理大量数据时,将数据分成多个小部分(页)来展示。这样可以提高用户体验,减少单次加载的数据量,从而加快页面响应速度,并且降低服务器和数据库的负载。
基本概念
- 页大小(Page Size):每一页显示的记录数量。
- 当前页码(Current Page Number):用户正在查看的页码。
- 总记录数(Total Record Count):数据库中满足条件的总记录数。
- 总页数(Total Pages):基于总记录数和页大小计算得出的总页数。
- 偏移量(Offset):从第一条记录开始到当前页的第一条记录之间的距离。
java
// 总记录数除以页大小(向上取整)得到总页数
int totalPages = (int) Math.ceil((double) totalRecords / pageSize);
基本步骤
升级示例5
在 DAO 层,获取总记录数,根据传入的偏移量(offset)和每页显示记录数(pageSize)来构建SQL查询语句。
java
// 修改公共接口全查方法,加入参数
public interface PublicInterface<E> {
/**
* 分页全查
* @param offset 偏移量
* @param pageSize 每页显示记录数
* @return
*/
List<E> findAll(Integer offset, Integer pageSize);
/**
* 获取总记录数
* @return int
*/
int findListCount();
}
java
// 添加 limit 条件
@Override
public List<SmbmsProvider> findAll(Integer offset, Integer pageSize) {
...
String sql = "select id,proCode,proName,proDesc,creationDate " +
"from smbms_provider order by creationDate desc limit ?,?";
ResultSet res = query(sql,offset,pageSize);
...
}
@Override
public int findListCount() {
try {
int count = 0;
if (getConnection()) {
String sql = "select count(1) count from smbms_provider";
ResultSet res = query(sql,null);
while(res.next()){
count = res.getInt("count");
}
}
return count;
} catch (Exception e) {
e.printStackTrace();
} finally {
closeResources(); // 释放资源
}
return 0;
}
在 Service 层,处理业务逻辑,包括根据当前页(pageNow)计算偏移量(offset)、根据总记录数(count)计算总页数(pageCount)。
java
public interface SmbmsProviderService {
/**
* 分页全查
* @param pageNow 当前页
* @param pageSize 每页显示记录数
* @return
*/
public List<SmbmsProvider> findAll(Integer pageNow, Integer pageSize);
/**
* 获得总页数
* @return int
*/
public int findListCount(Integer pageSize);
}
java
@Override
public List<SmbmsProvider> findAll(Integer pageNow, Integer pageSize) {
int offset = (pageNow - 1) * pageSize;
return smbmsProviderDao.findAll(offset, pageSize);
}
@Override
public int findListCount(Integer pageSize) {
// 获取总记录数
int count = smbmsProviderDao.findListCount();
// 总页数 = 总记录数%每页显count示记录数==0?(总记录数/每页显示记录数):(总记录数/每页显示记录数)+1
int pageCount = count % pageSize == 0 ? (count / pageSize) : (count / pageSize) + 1;
return pageCount;
}
在 Servlet 中,接收前端请求参数获取当前页码,调用 Service 层的方法获取总页数(pageCount),处理当前页(pageNow),最后将这些信息设置到请求属性中转发给视图。
java
int pageCount; // 总页数
int pageSize = 5; // 每页显示记录数
// 从请求参数中获取当前页码
int pageNow = 1;
if (request.getParameter("page") != null) {
pageNow = Integer.parseInt(request.getParameter("page"));
}
// 调用 Java 方法 获取供应商列表信息
List<SmbmsProvider> providerList = smbmsProviderService.findAll(pageNow,pageSize);
// 获得总页数
pageCount = smbmsProviderService.findListCount(pageSize);
// 将数据和分页信息放入请求属性
request.setAttribute("providerList", providerList);
request.setAttribute("pageNow", pageNow);
request.setAttribute("pageCount", pageCount);
在 index.jsp
实现分页导航的功能
jsp
<div class="pagination">
<a <c:if test="${pageNow == 1}">class="disabled"</c:if> <c:if test="${pageNow > 1}">href="/index?page=1"</c:if>>首页</a>
<a <c:if test="${pageNow == 1}">class="disabled"</c:if> <c:if test="${pageNow > 1}">href="/index?page=${pageNow - 1}"</c:if>>上一页</a>
<c:forEach begin="1" end="${pageCount}" var="i">
<c:choose>
<c:when test="${i == pageNow}">
<a class="active">${i}</a>
</c:when>
<c:otherwise>
<a href="/index?page=${i}">${i}</a>
</c:otherwise>
</c:choose>
</c:forEach>
<a <c:if test="${pageNow == pageCount}">class="disabled"</c:if> <c:if test="${pageNow < pageCount}">href="/index?page=${pageNow + 1}"</c:if>>下一页</a>
<a <c:if test="${pageNow == pageCount}">class="disabled"</c:if> <c:if test="${pageNow < pageCount}">href="/index?page=${pageCount}"</c:if>>尾页</a>
当前第 ${pageNow} / ${pageCount} 页
</div>