一个分页的类,分页的存储过程,分页的jsp示例

原创 2006年05月25日 10:08:00

一个分页的类,分页的存储过程,分页的jsp示例
一个分页的存储过程
一个调用存储过程的包装类
调用分页的类的jsp示例

基本思路:先调用存储过程从数据库中取出一部分数据,放入集合中进行缓存,然后从中取出一部分显示
在一页中,当要取下一页数据时,先从缓存中取数据,如果缓存中的数据不足,然后在调用存储过程从数
据库中取数据
  P.S.网上的网友也有很多分页的类,我写的分页的类,是和分页的存储过程相配合的。比较适合大数据量。
我还在测试1000万以上的数据量的速度。10万-100万的数据量,运行速度很快,不需要等待就可以取出结果,
时间大概在1-2秒,当然第一次运行的时候稍微慢一些!我还是在我的PIII 667上安装的
Windows Advance Server 2000 和Sql Server 2000  Tomcat 5.027,相信在更高的服务器上运行效果会更好!
BestPageBean.java是实现了调用分页存储过程的java类,BestPageBeanTest.java 中给出了使用方法。
package pagedata;
import java.sql.*;
import java.util.*;

public class BestPageBean {

    private int curDbPage=1;//从数据库中读取的是第几个页面的数据(按照一次读rowsPerGetDB条记录)
    private int maxDbPage;//数据库中共有多少个页面可共读取(按照一次读rowsPerGetDB条记录)
    private int sumRows;//数据库中的总记录数
    private int curPage=-1;
    /*当前显示的页面,-1表示从数据库中取出第一个页面的数据
     *-2 表示从数据库中取出当前页面的前一个页面的数据
     *-3 表示从数据库中取出当前页面的后一个页面的数据
     *-4 表示从数据库中取出最后一个页面的数据
     *正数说明是从缓存数组中取出相应的页面,不是从数据库中取数据,这个数字大小在1到multiple之间
     */
    private int maxPage;//如果按照每页显示的数据行数,则共可以显示的页面数
    private int displayPageNumber;//当前一共可以显示的页面
    private int multiple=10; //一次从数据库中取出的数据是每页显示的数据的倍数
    private int rowsPerPage=20;//每页显示的数据行数
    private int rowsPerGetDB=200;//一次从数据库中读取的记录,应等于rowsPerPage与multiple之积
    private int pageSumFromDBVector;//当前实际从数据库中读取的数据可供显示的页面数
    private Vector pageData;//存放一次要显示的数据
    private Vector dataFromDB;//一次从数据库中读取的数据

    //获得数据需要的参数
    private Connection conn;//数据库连接对象
    private int    i_desc=1;//按升序还是降序排列数据,0 升序,1降序
    private String s_WhereCondition="";//条件
    private String s_OrderFieldName="pubDate";//排序字段,不能为空!
    private String s_TableName="rss";//从那个表中取数据
    private String s_FieldsName="title,link,author,category,pubDate,description"; //要查询的数据列,* 为全部数据,
    private int    i_FieldsCount=6;  //要取出数据列的个数

    public BestPageBean() {
        pageData = new Vector();
        dataFromDB = new Vector();
    }
    public void setConnection(Connection con){
     conn=con;
    }
    public void setTableName(String s) {
        this.s_TableName =s;
        //取出字段个数
        try {
            Statement stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery("Select  count( *)   From   Syscolumns C, Sysobjects N where N.id=C.id and N.name='" +
                                             this.s_TableName + "'");
            rs.next();
            i_FieldsCount = rs.getInt(1);
            rs.close();
            stmt.close();
        } catch (SQLException e) {
          
            System.out.println("获得表的字段个数错误" + e.toString());
        }

    }
    public void setFieldsName(String s) {
        this.s_FieldsName =s;
        java.util.StringTokenizer st= new StringTokenizer(s,",");
        this.i_FieldsCount= st.countTokens();
    }
    public void setWhereCondition(String s) {
        this.s_WhereCondition =s;
        this.getSumPage();//重新设置了查询数据的条件,所有要重新计算总行数、总页数。
       
    }
    public void setOrderFieldName(String s) {
        this.s_OrderFieldName =s;
    }
    public void setDesc(int i) {
        this.i_desc =i;
    }

    public void setCurDbPage(int curDbPage) {
        //如果设置数据页,采取向前翻一个数据页,标记-2是让取当前页面的前一页数据
        //所以要先加上一页!取出的数据才刚好是要取的数据。
        this.curPage=-2;
        this.curDbPage = curDbPage+1;
    }
    public void setCurPage(int curPage) {
        this.curPage = curPage;
    }
    public void setRowsPerPage(int rowsPerPage) {
        this.rowsPerGetDB = rowsPerPage*multiple;
        this.rowsPerPage = rowsPerPage;
        this.getSumPage();//重新设置了每页显示的行数,所有要重新计算总页数。
    }
    public void setMultiple(int multiple) {
        this.rowsPerGetDB = rowsPerPage*multiple;
        this.multiple = multiple;
    }
    public int getCurDbPage() {
        return curDbPage;
    }
    public int getMaxDbPage() {
        return maxDbPage;
    }
    public int getSumRows() {
        return sumRows;
    }

    public int getCurPage() {
        return curPage;
    }

    public int getRowsPerPage() {
        return rowsPerPage;
    }
    public int getMaxPage() {
        return maxPage;
    }
    public int getDisplayPageNumber() {
        return displayPageNumber;
    }
    public int getMultiple() {
        return multiple;
    }
    public int getPageSumFromDBVector() {
        return pageSumFromDBVector;
    }
    //得到每页的数据
    public Vector getPageData() {
        pageData.clear();
        //需要从数据库中取数据(最前的数据)
        if(this.curPage==-1){
            this.curDbPage=1;
            getDataFromDB();
            this.curPage=1;
        }
        //需要从数据库中取数据(向前取数据)
        if(this.curPage==-2){
            if (this.curDbPage>1)
                this.curDbPage=this.curDbPage-1;
            else
                this.curDbPage=1;
            getDataFromDB();
            this.curPage=1;
        }
        //需要从数据库中取数据(向后取数据)
        if(this.curPage==-3){
            if (this.curDbPage<this.maxDbPage)
                this.curDbPage=this.curDbPage+1;
            else
                this.curDbPage=this.maxDbPage;
            getDataFromDB();
            this.curPage=1;
        }
        //需要从数据库中取数据(最后的数据)
        if(this.curPage==-4){
            this.curDbPage=this.maxDbPage;
            getDataFromDB();
            this.curPage=1;
        }

        //本次数据的起始页码
        this.displayPageNumber=(this.curDbPage-1)*this.multiple;
        //还需要判断如果数据不够的处理!
        int i_vectorsize=dataFromDB.size();
        int rows = (this.curPage - 1) * this.rowsPerPage;
        int i_shouldsize=rows + this.rowsPerPage;
        if (i_vectorsize<i_shouldsize)
            i_shouldsize=i_vectorsize;

        for (int i = rows; i < i_shouldsize; i++) {
            pageData.add(this.dataFromDB.get(i));
        }
        return pageData;
    }
    //从数据库得到数据
    private Vector getDataFromDB() {
        dataFromDB.clear();
        CallableStatement proc = null;
        try {
            proc = conn.prepareCall("{call GetRecordFromPage(?,?,?,?,?,?,?,?)}");
            proc.setString(1,this.s_TableName);
            proc.setString(2,this.s_FieldsName);
            proc.setString(3,this.s_OrderFieldName);
            proc.setInt(4,this.rowsPerGetDB);
            proc.setInt(5,this.curDbPage);
            proc.setInt(6,0);
            proc.setInt(7,this.i_desc);
            proc.setString(8,this.s_WhereCondition);
            ResultSet rs = proc.executeQuery();
            while (rs.next())
            {
                Object[] obj=new Object[this.i_FieldsCount];
                for (int i_count=1;i_count<=this.i_FieldsCount;i_count++){
                  obj[i_count-1]=rs.getObject(i_count);
                }
                dataFromDB.add(obj);
            }
            rs.close();
            proc.close();
         } catch (SQLException ex) {
            System.out.println("调用存储过程获得数据错误:"+ex.toString());
        }
         //判断一下从数据库中取出来的数据总数,计算出当前从数据库中取出的数据能够显示页数!
        int i_V_size=dataFromDB.size();
        if ((i_V_size % this.rowsPerPage)==0)
            this.pageSumFromDBVector= i_V_size/this.rowsPerPage;
        else
            this.pageSumFromDBVector= i_V_size/this.rowsPerPage +1;
        this.getSumPage();//每次从数据库中取数据,最好调用一下这个函数,以便得到数据库中最新的行数
        return dataFromDB;
    }

    //获得满足条件的记录总数
    private void getDataSumCount() {
        CallableStatement proc = null;
        this.sumRows=0;
        try {
            proc = conn.prepareCall("{call GetRecordFromPage(?,?,?,?,?,?,?,?)}");
            proc.setString(1,this.s_TableName);
            proc.setString(2,"");
            proc.setString(3,"");
            proc.setInt(4,0);
            proc.setInt(5,0);
            proc.setInt(6,1);
            proc.setInt(7,0);
            proc.setString(8,this.s_WhereCondition);
            ResultSet rs = proc.executeQuery();
            while (rs.next())
            {
                this.sumRows=rs.getInt(1);
            }
            rs.close();
            proc.close();

        } catch (SQLException ex) {
            System.out.println("调用存储过程获得总行数错误:"+ex.toString());
        }
    }
    //计算总页数
    private void countMaxPage(){
        //计算从数据库中可以取数据的总页数
        if (this.sumRows % this.rowsPerGetDB==0){
            this.maxDbPage = this.sumRows/this.rowsPerGetDB;
        }else{
            this.maxDbPage = this.sumRows/this.rowsPerGetDB + 1;
        }

        //计算从数据库中的数据可以显示的总页数
        if (this.sumRows % this.rowsPerPage==0){
             this.maxPage = this.sumRows/this.rowsPerPage;
         }else{
             this.maxPage = this.sumRows/this.rowsPerPage + 1;
         }

    }
    //返回总页数
    private void getSumPage(){
        getDataSumCount();
        countMaxPage();
    }
    //关闭数据库连接
    public void ColseConnection(){
     if (conn != null) {
         try {
             conn.close();
         } catch (SQLException ex) {
         }
     }
 }

}


BestPageBeanTest.java是测试示例
package pagedata;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class BestPageBeanTest {
 private String server = "";//服务器名称
 private String port = "1433"; //服务器端口
 private String dbname = "test"; //数据库名称
 private String user = "sa"; //连接数据库的用户名
 private String psw = "1"; //连接数据库的用户密码 
 private Connection con=null;
 
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  BestPageBean pagedata=new BestPageBean();
  
  BestPageBeanTest pagetest=new BestPageBeanTest();
     /**调用顺序:setConnection();设置连接
      * setTableName("tablname");设置表名
      * setFieldsName("id,name,sex,...");设置字段的列名
      * setRowsPerPage(30);设置每页显示的行数
      * 其他的参数,比如:一次从数据库中取出的数据是一页显示的行数的倍数
      * setMultiple(10)
      * 排序字段setOrderFieldName("id")//一定要在排序字段上建索引,否则,速度会很慢!!!
      * 升序还是降序setDesc(1) 0 升序,1降序
      * 等条件
      * 之后设置选择数据的条件
      * setWhereCondition("name='张三' and sex='男'");
      * 取数据getPageData();一次从数据库取出的数据是30×10=300行,
      * 但是只返回前30行,可以设置当前页来取出指定页码的数据,但这个页面不能大于10
      * setCurPage(int curPage)
      * 如果要取第301-600行数据则,设置
      * setCurDbPage(2)即可,要获得331-360行数据,则在设置
      * setCurPage(2),然后调用
      * getPageData()就返回你指定的数据集。
      * 缺省取出的是满足条件的第一页(每页显示的行数与一次从倍数的乘积300)的数据
      */
  
  pagedata.setConnection(pagetest.getConnection());
  pagedata.setWhereCondition("");
  pagedata.getPageData();
  System.out.println( pagedata.getSumRows());
 }
// 建立和数据库的连接
    public Connection getConnection(){
        //连接数据库
        String sDBDriver = "com.microsoft.jdbc.sqlserver.SQLServerDriver";
        String sConnStr =
                "jdbc:microsoft:sqlserver://" + server + ":" + port +
                ";DatabaseName=" +dbname+";SelectMethod=cursor;";
        //加载驱动
        try {
            Class.forName(sDBDriver);
        } catch (java.lang.ClassNotFoundException e1) {
           
            System.exit(0);
        }
        try {
            con = DriverManager.getConnection(sConnStr, user, psw);
        } catch (SQLException e) {
           
            System.exit(0);
        }
        System.out.println("已经获得DataSource!");
        return con;
    }

}


存储过程getRecordFromPage的内容
//getRecordFromPage.sql

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[getRecordFromPage]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[getRecordFromPage]
GO

SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS OFF
GO

CREATE PROCEDURE getRecordFromPage
@tblName varchar(255), -- 表名
@strGetFields varchar(1000) = '*', -- 需要返回的列
@fldName varchar(255)='', -- 排序的字段名
@PageSize int = 10, -- 页尺寸
@PageIndex int = 1, -- 页码
@doCount bit = 0, -- 返回记录总数, 非 0 值则返回
@OrderType bit = 0, -- 设置排序类型, 非 0 值则降序
@strWhere varchar(1500) = '' -- 查询条件 (注意: 不要加 where)
AS
declare @strSQL varchar(5000) -- 主语句
declare @strTmp varchar(110) -- 临时变量
declare @strOrder varchar(400) -- 排序类型
if @doCount != 0
begin
  if @strWhere !=''
     set @strSQL = 'select count(*) as Total from [' + @tblName + '] where '+@strWhere
  else
     set @strSQL = 'select count(*) as Total from [' + @tblName + ']'
end
--以上代码的意思是如果@doCount传递过来的不是0,就执行总数统计。以下的所有代码都是@doCount为0的情况:
else
begin
    if @OrderType != 0
    begin
      set @strTmp = '<=(select min'
      set @strOrder = ' order by [' + @fldName +'] desc'
    --如果@OrderType不是0,就执行降序,这句很重要!
    end
    else
    begin
      set @strTmp = '>=(select max'
      set @strOrder =' order by [' + @fldName +']  '
    end

    if @PageIndex > 1
    begin --以下代码赋予了@strSQL以真正执行的SQL代码
         set @strSQL = 'select top ' + str(@PageSize) +' '+@strGetFields+ ' from ['
                   + @tblName + '] where [' + @fldName + ']' + @strTmp + '(['
                   + @fldName + ']) from (select top ' + str((@PageIndex-1)*@PageSize) +' ['
                   + @fldName + ']  from [' + @tblName + '] '
                   + @strOrder + ') as tblTmp)  '+ @strOrder
         if @strWhere != ''
          set @strSQL = 'select top ' + str(@PageSize) +' '+@strGetFields+ ' from ['
                  + @tblName + '] where [' + @fldName + ']' + @strTmp + '(['
                  + @fldName + ']) from (select top ' + str((@PageIndex-1)*@PageSize) + ' ['
                  + @fldName + '] from [' + @tblName + '] where ' + @strWhere + ' '
                  + @strOrder + ') as tblTmp) and ' + @strWhere + ' ' + @strOrder
     end
     else --如果是第一页就执行以上代码,这样会加快执行速度
     begin
      if @strWhere != ''
      begin
           set @strSQL = 'select top ' + str(@PageSize) +' '+@strGetFields+ ' from [' + @tblName + '] where  ' + @strWhere + ' ' + @strOrder
      end
      else
      begin
           set @strSQL = 'select top ' + str(@PageSize) +' '+@strGetFields+ ' from ['+ @tblName + '] '+ @strOrder
      end
    
     end
end
exec (@strSQL)
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO

 

 

vector.jsp是分页的jsp文件,同时还用到了vector_servlet.java 中Servlet类,
vector_servlet.java内容如下:
package pagedata;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.sql.DataSource;

import java.io.*;
import java.sql.Connection;


public class vector_servlet extends HttpServlet {
   
 private static final long serialVersionUID = 1L;
 private static final String CONTENT_TYPE = "text/html; charset=GBK";
    BestPageBean data;
    //Initialize global variables
    public void init() throws ServletException {
     Connection con=null;
     //Tomcat中配置
        DataSource ds = null;
        try{
            Context initCtx = new InitialContext();
            Context envCtx = (Context) initCtx.lookup("java:comp/env");
            //从Context中lookup数据源。
            ds = (DataSource)envCtx.lookup("jdbc/mssql");
            if(ds!=null) {
                System.out.println("使用jndi获得DataSource!");
                con = ds.getConnection();
            }
            else {
                System.out.println("连接失败!");
               
            }
        }
        catch(Exception ne){System.out.println("连接失败!");}
        data =new BestPageBean();
        data.setConnection(con);
        data.setWhereCondition("");
        data.setMultiple(20);
        data.setRowsPerPage(20);
        data.getPageData();//初始化数据
    }

    //Process the HTTP Get request
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws
            ServletException, IOException {
        response.setContentType(CONTENT_TYPE);
        String pagenumber=request.getParameter("page");
        String dbpage=request.getParameter("dbpage");
        if (pagenumber!=null){
            data.setCurPage(Integer.valueOf(pagenumber).intValue());
        }
        if (dbpage!=null){
            data.setCurDbPage(Integer.valueOf(dbpage).intValue());
        }
        request.setAttribute("pageCtl",data);
        javax.servlet.RequestDispatcher
                dis=request.getRequestDispatcher("/vector.jsp");
        dis.forward(request,response);
    }

    //Process the HTTP Post request
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws
            ServletException, IOException {
        doGet(request, response);
    }

    //Clean up resources
    public void destroy() {
    }
}


vector.jsp内容如下:

<%@ page contentType="text/html; charset=GBK" %>
<%@ page import="pagedata.BestPageBean" %>

<html>
<head>
<title>新闻列表</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>


<script language="JavaScript" type="">
<!--
function MM_jumpMenu(targ,selObj,restore){ //v3.0
  eval(targ+".location='"+selObj.options[selObj.selectedIndex].value+"'");
  if (restore) selObj.selectedIndex=0;
}
//-->
</script>

 

 <body bgcolor="#ffffff" text="#000000" vlink="#669900" alink="#0000FF" link="#3300FF">
<table width="85%" border="0" align="right">
<%
   BestPageBean pagedata=(BestPageBean)request.getAttribute("pageCtl");
//  java.util.Vector v=(java.util.Vector)request.getAttribute("pageCtl");
  java.util.Vector v=  pagedata.getPageData();

  java.util.Enumeration  e=v.elements();
  int rows=0;
  while(e.hasMoreElements())
  {
    Object[] obj=(Object[])e.nextElement();
   if ((rows%2)==0) {
     rows++;
    %>
     <tr bgcolor="#eeeeff">
       <td align="left" width="55%">
         <div> <a href="<%=obj[1]%>"><%=obj[0]%></a></div>
       </td>
       <td  align="left"  width="15%">
         <div> <%=  obj[2] %> </div>
       </td>
      <td  align="left"  width="15%">
         <div><%=  obj[3] %></div>
       </td>
      <td  align= "center"  width="15%">
         <div> <%=  obj[4] %> </div>
       </td>
     </tr>
 <%} else { rows++; %>
     <tr >
       <td align="left" width="55%">
         <div> <a href="<%=obj[1]%>"><%=obj[0]%></a></div>
       </td>
       <td  align="left"  width="15%">
         <div> <%=  obj[2] %> </div>
       </td>
      <td  align="left"  width="15%">
         <div> <%=  obj[3] %></div>
       </td>
      <td  align= "center"  width="15%">
         <div> <%=  obj[4] %> </div>
       </td>
     </tr>

 <%} } %>
  <tr>
   <td  align= "center"  colspan="4">
    <div>
     <form name="form1" action="">
     <%--  共<%=pagedata.getSumRows()%>行 <%=pagedata.getMaxPage()%>页 当前<%=pagedata.getDisplayPageNumber()+pagedata.getCurPage()%>页--%>
     共<%=pagedata.getSumRows()%>行 当前<%=pagedata.getDisplayPageNumber()+pagedata.getCurPage()%>页

     <% if(pagedata.getCurDbPage()==1){
          out.print(" 首页 前"+pagedata.getMultiple()+"页");
        }else{
     %>
        <a href="vector_servlet?page=-1">首页</a>
        <a href="vector_servlet?page=-2">前<%=pagedata.getMultiple()%>页</a>

    <%}%>
     <%   int s_beginPagenumber=pagedata.getDisplayPageNumber();
          int s_disp=0;
          for(int i=1;i<=pagedata.getPageSumFromDBVector();i++)  {
             s_disp=s_beginPagenumber+i;
       %>
         <a href="vector_servlet?page=<%=i%>"><%=s_disp%></a>
     <% }%>
    <%  if(pagedata.getCurDbPage()==pagedata.getMaxDbPage()){
            out.print("下"+pagedata.getMultiple()+"页 尾页");
      }else{
    %>
    <a href="vector_servlet?page=-3">下<%=pagedata.getMultiple()%>页</a>
    <a href="vector_servlet?page=-4">尾页</a>
    <%}%>
    <select name="menu1" onChange="MM_jumpMenu('parent',this,0)" size="1">
         <% for(int i=1;i<=pagedata.getMaxDbPage();i++)  {
           if (i!= pagedata.getCurDbPage()){
           %>
             <option value="vector_servlet?dbpage=<%=i%>"><%=i-1%></option>
           <%}else{%>
             <option value="vector_servlet?dbpage=<%=i%>" selected><%=i-1%></option>
           <%}}%>
      </select>
    </form>
       </div>
   </td>
</tr>

</table>


</body>
</html>


在web中,先从servlet进入
web.xml的内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
  <display-name>WebModule1</display-name>
 
  <servlet>
    <servlet-name>vector_servlet</servlet-name>
    <servlet-class>pagedata.vector_servlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>vector_servlet</servlet-name>
    <url-pattern>/vector_servlet</url-pattern>
  </servlet-mapping>
</web-app>
其他的请自己配置。

相关文章推荐

分页存储过程示例系统

  • 2008年12月06日 17:16
  • 617KB
  • 下载

SQL 2分查找法 通用分页存储过程算法 改成.net类实现

using System;namespace CountryPark.DAL{    /**////     /// PageList 的摘要说明。    ///     public sealed ...

不使用存储过程的通用分页类

  • 2006年08月24日 11:11
  • 10KB
  • 下载

Oralce 写一个分页的存储过程

有返回值的存储过程(列表 结果集)  案例:编写一个过程,输入部门编号,返回该部门所有员工的信 息。对该题的分析如下: 由于Oracle的存储过程没有返回值,它的所有返回值都是通过out 参数...
  • c622724
  • c622724
  • 2012年12月21日 22:08
  • 685

ASP类+存储过程进行高效数据分页

  • 2007年10月25日 16:29
  • 562KB
  • 下载

全能增删查分页存储过程

  • 2017年11月16日 14:02
  • 4KB
  • 下载

一个分页存储过程【鸡蛋】

ALTER PROCEDURE [dbo].[AdminGetUserList] @PageSize INT, --页尺寸(每页显示数据的数量) @PageIndex INT, ...

分页存储过程

  • 2016年08月02日 22:50
  • 3KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:一个分页的类,分页的存储过程,分页的jsp示例
举报原因:
原因补充:

(最多只允许输入30个字)