您的位置:首页 > Web前端 > JavaScript

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

2006-05-25 10:08 507 查看
一个分页的类,分页的存储过程,分页的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>
其他的请自己配置。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: