`

数据库分页

阅读更多
首先说数据库,里边只有一张表bean,三个字段id, title和add_date。

-- beancreate table bean(    id bigint, -- 主键    title varchar(100), -- 标题    add_date datetime -- 时间);        对应的Bean.java咱们就不用写了,只看一看后台去数据库读取数据库的BeanServlet.java。

package anni;
import java.io.*;
import java.sql.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class BeanServlet extends HttpServlet {    
public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {        
Connection conn = null;       
 Statement state = null;       
 ResultSet rs = null;       
 // 获得当前页码        
int pageNo = 1;        
try {            
pageNo = Integer.parseInt(request.getParameter("pageNo"));    
    } catch(Exception ex) {        }        
if (pageNo < 1) {      
      pageNo = 1;    
    }     
   request.setAttribute("pageNo", pageNo);    
    List list = new ArrayList();     
   int count = 0;    
    // 根据页码从数据库中获得对应的数据   
     try {      
      conn = DbUtils.getConn();      
      state = conn.createStatement();      
      rs = state.executeQuery("select limit " + (pageNo * 5 - 5) + " 5 * from bean");       
     while (rs.next()) {        
        Bean bean = new Bean();      
          bean.setId(rs.getLong(1));      
          bean.setTitle(rs.getString(2));      
        bean.setAddDate(rs.getTimestamp(3));       
         list.add(bean);            }     
       rs.close();      
      rs = state.executeQuery("select count(*) from bean");        
    if (rs.next()) {       
         count = rs.getInt(1);      
      }    
    } catch(Exception ex) {     
       ex.printStackTrace();     
   } finally {       
     DbUtils.close(rs, state, conn);  
      }     
   request.setAttribute("count", count);     
   request.setAttribute("list", list);        request.getRequestDispatcher("/query.jsp").forward(request, response);  
  }
}       
 代码长了,分三段来看:

// 获得当前页码
int pageNo = 1;
try {    
pageNo = Integer.parseInt(request.getParameter("pageNo"));
} catch(Exception ex) {
}if (pageNo < 1) {  
  pageNo = 1;
}request.setAttribute("pageNo", pageNo);        
        这里pageNo代表当前的页码,如果没有传递pageNo参数,默认显示第一页,为此我们在解析request中参数时要捕获对应的异常,如果没有输入或者参数不是一个数字时pageNo就还是等于1。

rs = state.executeQuery("select limit " + (pageNo * 5 - 5) + " 5 * from bean");                这里我们拼了一个sql语句,用来从(pageNo * 5 - 5)开始查询五个记录,这条sql语句是hsqldb数据库特有的分页语句。

(pageNo * 5 - 5)用来计算pageNo这页第一条记录的行号,如果是第一页pageNo = 1,pageNo * 5 - 5 = 0。这里的行号跟咱们平常使用的数组索引一样,0代表第一个条记录,这样我们第一页就会显示0,1,2,3,4五条记录。如果是第二页pageNo = 2,pageNo * 5 - 5 = 5,我们就会在第二页看到5,6,7,8,9五条记录。这样正好与我们预期的一致。

rs = state.executeQuery("select count(*) from bean");                最后记得要获得数据库中一共有几条记录,我们要用它来计算一共要分几页。

计算方法是count / 5 + 1,比如现在有39条记录,39 / 5 + 1 = 8,一共分8页。

经过BeanServlet.java的处理,request里有三个变量,list保存当前页面显示的结果,pageNo代表当前页码,count代表数据库中一共有多少条记录,这三个变量会在query.jsp中作为原始数据显示最终的结果。

            <tbody><%    SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日");    List list = (List) request.getAttribute("list");    if (list != null && list.size() != 0) {        for (int i = 0; i < list.size(); i++) {            Bean bean = (Bean) list.get(i);%>                <tr class="<%=(i % 2 == 1 ? "odd" : "even")%>">                    <td><%=bean.getId()%></td>                    <td><%=bean.getTitle()%></td>                    <td><%=format.format(bean.getAddDate())%></td>                </tr><%        }    } else {%>                <tr>                    <td colspan="3">没有数据</td>                </tr><%    }%>            </tbody>        循环显示list中当前页面的数据并不是新鲜事物,我们只是判断了list是否存在,list里是否有数据,如果这两个条件不符合,就显示“没有数据”作为提示。

下面是重头戏了,仔细研究一下如何使用pageNo(当前页码)和count(数据总数)显示出分页工具栏,虽然只是进行简单的四则运算,但要是平常不注意训练算法,想一次写好也不容易。

分页栏部分的代码如下:

        <div><%    Integer pageNo = (Integer) request.getAttribute("pageNo");    Integer count = (Integer) request.getAttribute("count");    Integer pageCount = count / 5 + 1;    if (pageNo == 1) {%>            <span class="unuse">[第一页]</span>            <span class="unuse">[上一页]</span><%    } else {%>            <span><a href="?pageNo=1">[第一页]</a></span>            <span><a href="?pageNo=<%=pageNo - 1%>">[上一页]</a></span><%    }%><%    for (int i = 1; i <= pageCount; i++) {        if (i == pageNo) {%>            <span class="currentPage"><%=i%></span><%        } else {%>            <span><a href="?pageNo=<%=i%>"><%=i%></a></span><%        }    }%><%    if (pageNo == pageCount) {%>            <span class="unuse">[下一页]</span>            <span class="unuse">[最后一页]</span><%    } else {%>            <span><a href="?pageNo=<%=pageNo + 1%>">[下一页]</a></span>            <span><a href="?pageNo=<%=pageCount%>">[最后一页]</a></span><%    }%>            <form style="display:inline;">                <select name="pageNo"><%    for (int i = 1; i <= pageCount; i++) {%>                    <option value="<%=i%>" <%=(i == pageNo ? "selected" : "")%>><%=i%></option><%    }%>                </select>                <input type="submit" value="go" />            </form>        </div>        首先我们从request中取得pageNo(当前页码)和count(数据总数)两个变量,为了下面计算简便先用它俩计算出总页数 int pageCount = count / 5 + 1; 。

    if (pageNo == 1) {%>            <span class="unuse">[第一页]</span>            <span class="unuse">[上一页]</span><%    } else {%>            <span><a href="?pageNo=1">[第一页]</a></span>            <span><a href="?pageNo=<%=pageNo - 1%>">[上一页]</a></span><%    }%>        这段代码生成“[第一页] [上一页]”,如果pageNo == 1说明当前页已经是第一页了,这时既不需要[第一页]这个链接,也不需要[上一页]了。对应的“[下一页] [最后一页]”处理方法与之类似,只是判断条件要写成pageNo == pageCount,判断是否已经是最后一页了。

<%    for (int i = 1; i <= pageCount; i++) {        if (i == pageNo) {%>            <span class="currentPage"><%=i%></span><%        } else {%>            <span><a href="?pageNo=<%=i%>"><%=i%></a></span><%        }    }%>        中间页码部分直接使用循环就能输出来,循环从i = 1开始直到i <= 8,最后就是我们看到的1,2,3,4,5,6,7,8。既然pageNo是从1开始算的,我们这里就也从i = 1起步了。如果在i == pageNo的时候,说明这是当前页,不需要链接,再加上一个class="currentPage"突出显示。

            <form style="display:inline;">                <select name="pageNo"><%    for (int i = 1; i <= pageCount; i++) {%>                    <option value="<%=i%>" <%=(i == pageNo ? "selected" : "")%>><%=i%></option><%    }%>                </select>                <input type="submit" value="go" />            </form>        这个select下拉选择框的实现与上面相似,循环一下,遇到i == pageNo的时候就输出一个selected默认显示到select里,在选中想跳转的页码,点击下面的go按钮提交,跳转的效果也前面的超链接相同。

范例在15-01。

15.2. 使用jstl改写分页
jsp的代码让人眼晕,我们现在把分页中所有的jsp代码都换成jstl标签,这些我们要导入三个标签:core,fmt,functions。

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%><%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%><%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>        其中core提供循环标签(forEach)和判断标签(if),fmt为我们格式化日期,functions可以判断list的长度。

使用它们,下面显示记录结果的代码最终变成这幅模样。

            <tbody><c:forEach var="item" items="${list}" varStatus="status">  <c:set var="row" value="${status.index % 2 != 0 ? 'odd' : 'even'}"/>                <tr class="${row}">                    <td>${item.id}</td>                    <td>${item.title}</td>                    <td><fmt:formatDate pattern="yyyy年MM月dd日" value="${item.addDate}"/></td>                </tr></c:forEach><c:if test="${empty list || fn:length(list) == 0}">                <tr>                    <td colspan="3">没有数据</td>                </tr></c:if>            </tbody>        forEach用来循环${list}中的内容,把每个元素保存到局部变量item中,供下面使用。

fmt:formatDate 是专门用于日期格式化显示的标签,相当于我们刚刚在jsp中使用的SimpleDateFormat,pattern部分设置期望显示的日期格式,最后它就会把value中的${item.addDate}显示成“2008年04-01”的格式。

c:if也是一个非常常用的标签,它用来判断test=""中指定的el表达式的真假,如果是true就执行标签内部的内容,否则就跳过。很难受的是jstl中没有else的部分,想实现else必须写两次if两次test,很麻烦,但真就是jsp的局限。

fn:length(list) 是functions标签部分为我们提供的扩展功能,因为el表达式中不能直接调用变量的方法,需要判断list长度的时候无法使用 list.size(),只能通过fn:length(list)走一下弯路了,虽然它的功能十分有限,但也为我们提供了一条尽量不写jsp的途径,忍忍吧。

后面分页部分的功能随便帖一下就好,只是循环和判断的组合而已。

        <div><c:set var="pageCount" value="${count / 5 + 1}"/><c:if test="${pageNo == 1}">            <span class="unuse">[第一页]</span>            <span class="unuse">[上一页]</span></c:if><c:if test="${pageNo != 1}">            <span><a href="?pageNo=1">[第一页]</a></span>            <span><a href="?pageNo=${pageNo - 1}">[上一页]</a></span></c:if><c:forEach begin="1" end="${pageCount}" varStatus="status">    <c:if test="${status.index == pageNo}">            <span class="currentPage">${status.index}</span>    </c:if>    <c:if test="${status.index != pageNo}">            <span><a href="?pageNo=${status.index}">${status.index}</a></span>    </c:if></c:forEach><c:if test="${pageNo == pageCount}">            <span class="unuse">[下一页]</span>            <span class="unuse">[最后一页]</span></c:if><c:if test="${pageNo != pageCount}">            <span><a href="?pageNo=${pageNo + 1}">[下一页]</a></span>            <span><a href="?pageNo=${pageCount}">[最后一页]</a></span></c:if>            <form style="display:inline;">                <select name="pageNo"><c:forEach begin="1" end="${pageCount}" varStatus="status">                    <option value="${status.index}" ${status.index == pageNo ? 'selected' : ''}>${status.index}</option></c:forEach>                </select>                <input type="submit" value="go" />            </form>        </div>        这里可以看到forEach的另一种用法,begin="1"从i = 1开始循环,end="${pageCount}"会一直循环到i <= pageCount结束,这帮助我们实现简单循环,以后还可以使用varStatus="status"获得当前行号信息,这些变量最后都可以在循环体中使用到。
http://dinghaoliang.blog.163.com/blog/static/12654071420101205366346/
分享到:
评论

相关推荐

    Qt编写的数据库分页demo

    **Qt编写的数据库分页demo**是一个用于展示如何在Qt应用程序中实现高效、用户友好的数据库数据分页功能的示例项目。这个demo的核心在于它能够处理大量的数据,如千万级记录,同时提供流畅的用户体验,包括上一页、...

    各数据库分页语法支持

    ### 各数据库分页语法支持 #### 概述 在数据库操作中,分页查询是一项非常常见的需求。分页能够帮助我们有效地管理大量的数据记录,提高数据查询的效率和用户体验。不同的数据库系统提供了不同的分页机制,本文将...

    数据库分页大全及示例

    数据库分页是数据库管理系统中用于实现用户界面分段显示大量数据的一种技术。它允许用户逐步浏览数据集,而不需要一次性加载所有记录,从而提高用户体验并减少服务器资源的消耗。本篇文章将详细介绍如何在不同的...

    基于VB6+ADO+ListView制作的一个数据库分页显示程序

    基于VB6+ADO+ListView制作的一个数据库分页显示程序 基于VB6+ADO+ListView制作的一个数据库分页显示程序是使用VB6开发的一款数据库分页显示程序,使用ADO(ActiveX Data Objects)技术访问数据库,并使用ListView...

    asp+数据库分页显示

    在ASP(Active Server Pages)与SQL Server的组合中,实现数据库分页显示是一项常见的任务,尤其是在构建大型数据驱动的Web应用程序时。分页能够有效地管理大量数据,避免一次性加载所有记录,提高页面加载速度,同时...

    Qt数据库分页显示

    本教程将深入探讨如何在Qt应用中实现SQLite数据库的数据分页显示。 首先,我们需要在Qt项目中集成SQLite数据库支持。在Qt Creator中,新建一个Qt Widgets Application项目,然后在.pro文件中添加`QT += sql`来启用...

    易语言测试源码,易语言数据库分页显示

    在这个"易语言测试源码,易语言数据库分页显示"的压缩包中,我们关注的是如何在易语言中实现数据库数据的分页显示功能。 数据库分页显示是常见的数据处理技术,尤其在网页或应用程序中,当数据量较大时,为了提高...

    易语言数据库分页显示源码

    在IT行业中,数据库分页显示是一项常见的功能,尤其在网页应用和桌面软件中,用于处理大量数据时,分页能够有效提高用户体验,避免一次性加载过多数据导致系统性能下降。本示例是基于易语言(EasyLanguage)和MySQL...

    常用的数据库分页语句

    数据库分页是数据库管理系统中一个重要的查询技术,用于在大量数据中实现高效的检索。当用户在网页或应用程序中浏览数据时,通常不希望一次性加载所有记录,而是分页显示,这样可以减少网络传输的数据量,提高用户...

    Struts分页演示工程(一次性读取后台分页,而非数据库分页)

    一、此演示使MS Sql Server 2000默认安装的的数据库northwind,使用CUSTOMERS表中的数据做为演示,不用自已到处找表或自已建表 ... &lt;br&gt;(一次性读取后台分页,而非数据库分页) &lt;br&gt;经自已调试通过的完整工程。

    数据库分页用存储过程实现的

    数据库分页 用存储过程实现的 数据库分页 用存储过程实现的 数据库分页 用存储过程实现的 数据库分页 用存储过程实现的

    易语言一个简单的数据库分页例程

    在这个“易语言一个简单的数据库分页例程”中,我们将探讨如何使用易语言来实现数据库数据的分页显示。 在数据库应用中,分页是常见的数据展示方式,它可以帮助用户更有效地浏览大量数据,避免一次性加载所有数据...

    数据库分页技术-C3p0手动封装

    数据库分页技术是大型Web应用中不可或缺的一部分,它有效地帮助用户在海量数据中浏览和查找信息,而不会一次性加载所有数据导致性能下降。本实例主要介绍了如何利用C3p0数据库连接池配合分层技术和JSTL(JavaServer ...

    几条常见的数据库分页SQL 语句

    几条常见的数据库分页SQL 语句,针对oracle,sqlserver,mysql三种常见数据库的分页显示。

    Java Servlet 数据库分页功能演示.rar

    在本示例中,"Java Servlet 数据库分页功能演示" 提供了一个具体的应用场景,即如何在Servlet中实现数据库数据的分页展示。这在处理大量数据时尤其重要,因为它提高了用户界面的性能并提供了更好的用户体验。 首先...

    一个通用的数据库分页类

    数据库分页是Web开发中非常常见的一种技术,用于在大量数据中实现高效的浏览体验,避免一次性加载所有数据导致页面响应慢或内存消耗过大。这里提到的"一个通用的数据库分页类",很可能是PHP中设计的一个可复用的分页...

    分页代码 最完美的sql2005数据库分页,可以随便用的~!嘎嘎

    最完美的sql2005数据库分页,可以随便用的~!嘎嘎最完美的sql2005数据库分页,可以随便用的~!嘎嘎最完美的sql2005数据库分页,可以随便用的~!嘎嘎最完美的sql2005数据库分页,可以随便用的~!嘎嘎

    数据库分页优化技术分析与实现

    在介绍数据库分页优化技术时,首先应当明确传统分页查询方法所存在的问题。在传统方法中,分页查询通常采用(limit, offset)方式,但这种方式随着数据量的增长及翻页数量的增加,查询效率会显著降低。尤其在数据量较...

    数据库分页方法

    ### 数据库分页方法 在处理大量数据时,分页技术是提高用户体验、优化系统性能的重要手段之一。本文将深入探讨数据库分页的基本概念、原理以及实现方式,并通过具体的SQL语句示例来帮助读者更好地理解和掌握这一...

Global site tag (gtag.js) - Google Analytics