我是FE,也是Fe

前端来源于不断的点滴积累。我一直在努力。

统计

留言簿(15)

阅读排行榜

评论排行榜

Sql server 2000 jdbc 查询分页解决方案

(今天看自己的blog,发现上次更新已经是3-20,坚持每周更新blog! )

之所以要把sql server 2000 jdbc 分页单独来说说,又两个地方还是值得一提,一者是sql server 2000要实现数据库分页是比较麻烦的事情。二者是jdbc查询出多个ResultSet 的取法。

先在项目的classpath中添加msbase.jar,mssqlserver.jar,msutil.jar 怎么来的就不多废话了。需要说的是我最先用的sql server 2005 jdbc驱动sqljdbc.jar放到项目中,后来的程序是报错的。回头想想,报错有理,sql server 2005 已经支持rownum 分页了。

先说说sql server 2000的分页的实现,目前实现方法大概是那三种。我个人还是喜欢使用存储过程,原因是使用非常方便,至于使用的存储过程,这里还是放出来看看,估计大家用的都大同小异。

IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[Pr_QueryByPage]') AND OBJECTPROPERTY(id,N'IsProcedure') = 1)
BEGIN
EXEC dbo.sp_executesql @statement = N'create     procedure   [dbo].[Pr_QueryByPage]   
@sqlstr   nvarchar(4000),   --查询sql  
@currentpage   int, --第页记录条数  
@pagesize   int --每页显示记录 
as   
set   nocount   on   
declare   @P1   int, --P1是游标的ID  
@rowcount   int   
exec   sp_cursoropen   @P1   output,@sqlstr,@scrollopt=1,@ccopt=1,@rowcount=@rowcount   output   
select   ceiling(1.0*@rowcount/@pagesize)   as TotalPage,@rowcount as [RowCount] 
set   @currentpage=(@currentpage-1)*@pagesize+1   
exec   sp_cursorfetch   @P1,16,@currentpage,@pagesize     
exec   sp_cursorclose   @P1   
set   nocount   off  ' 
END
GO

这个存储过程的实现,使用了三个系统存储过程sp_cursoropen ,sp_cursorfetch ,sp_cursorclose 从字面上的意思大概是他叫结果集使用游标打开,然后读取其中的@pageSize条记录,所以单从查询上来讲,性能是不及使用select top 之类的实现。

 

使用起来非常容易,exec Pr_QueryByPage 'select * from yourtable',1,10  就可以了麻烦的是他返回的是三张表。第一张表是查询的表,但是没有记录。第二个表一行两列,第一个列是总页数,第二个列是总记录条数。第三张表才是需要的数据。这就造成了取的时候有点小麻烦,因为之前只知道,在.net中可以直接fill(DataSet),然后DataSet里面可取DataTable。但是在jdbc里面我映像中ResultSet 只能容一张表。后来找了一些资料,原来PreparedStatement,CallableStatement,Statement都支持查询返回多个ResultSet ,好了,非常好。 下面是我使用CallableStatemnt取到的结果集。

 

CallableStatement cs = conn.prepareCall("exec Pr_QueryByPage 'select * from ckdmzd',1,10");
            ResultSet rs = null;
            /**
             * execute returns :
             *     true : returns ResultSet(s)
             *  false: returns rows affected
             */
            boolean hasResultSet = cs.execute();
            if(hasResultSet){
                /**
                 * skip the first ResultSet
                 */
                rs=cs.getResultSet();
                /**
                 * second ResultSet : pageCount & recordCount
                 */
                if(cs.getMoreResults()){
                    rs=cs.getResultSet();
                    while(rs.next()){
                        String pageCount=rs.getString(1);
                        String recordCount=rs.getString(2);
                    }
                }
                /**
                 * the thrid one is the paged result
                 */
                if(cs.getMoreResults()){
                    rs=cs.getResultSet();
                    while(rs.next()){
                        // do somthing with ResultSet
                    }
                }
            }

这样就实现了分页,网上很多人测试了,这个方法的性能不及别的方法,这里我要指出的是,别的方法是不能返回总的记录条数的。而要知道总的记录条数,通常需要select count(*) from ( your sql) 这两次查询叫起来的时间未必会少。

总结

使用上述方法实现sql server 2000 jdbc 分页,使用方便,性能还说的过去。我不知道sql server 2005 的查询性能是否又提升。

posted on 2009-04-03 16:55 衡锋 阅读(1635) 评论(1)  编辑  收藏 所属分类: j2ee

评论

# re: Sql server 2000 jdbc 查询分页解决方案 2011-09-15 08:32 tb

2005 性能比较高点   回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航: