知识大全 高效SQL分页存储过程(2)
Posted 知
篇首语:弱龄寄事外,委怀在琴书。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 高效SQL分页存储过程(2)相关的知识,希望对你有一定的参考价值。
高效SQL分页存储过程(2) 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
Book类 负责查询数据库 把结果放到一个ArrayList中
package bean;
import java sql *;
import java util ArrayList;
public class Book
private String bookname;
private String author;
private String price;
public Book(String name String author String price)
this bookname=name;
this author=author;
this price=price;
public void setBookname(String bookname)
this bookname=bookname;
public void setAuthor(String Author)
this author=author;
public void setPrice(String price)
this price=price;
public String getBookname()
return bookname;
public String getAuthor()
return author;
public String getPrice()
return price;
public static ArrayList getAllBook() throws Exception
String sql= select * from book ;
SqlBean sq=new SqlBean();
ArrayList arrayList=new ArrayList();
try
ResultSet resultSet=sq select(sql);
while(resultSet next())
String name=resultSet getString( name );
String author=resultSet getString( author );
String price=resultSet getString( price );
Book book=new Book(name author price);
arrayList add(book);
resultSet close();
catch(SQLException e)
System out println( 数据库错误 +e toString());
return arrayList;
这个是SqlBook 负责和数据库建立一个连接的Bean
package bean;
import java sql Connection;
import java sql DriverManager;
import java sql ResultSet;
import java sql Statement;
public class SqlBean
String url= jdbc:microsoft:sqlserver://localhost: ;DatabaseName=eBookStore ;
Connection con=null;
Statement sta=null;
public SqlBean()
try
Class forName( microsoft jdbc sqlserver SQLServerDriver );
con=DriverManager getConnection(url sa );
sta=con createStatement();
catch(Exception e)
System out println( 连接错误 +e toString());
public ResultSet select(String selects) throws Exception
return sta executeQuery(selects);
…………………………………………………………………………
这个是负责显示分页的JSP页 pagetest jsp
<%@ taglib uri= /WEB INF/struts tld prefix= %>
<%@ taglib uri= /WEB INF/struts bean tld prefix= bean %>
<%@ taglib uri= /WEB INF/struts logic tld prefix= logic %>
<%@ page contentType= text/;charset=gb %>
<: locale= true >
<head>
</head>
<body>
<table border= >
<tr><th>书名</th><th>作者</th><th>价格</th></tr>
<logic:present name= result >
<logic:iterate id= book name= result type= bean Book >
<logic:present name= book >
<tr>
<td><bean:write name= book property= bookname /></td>
<td><bean:write name= book property= author /></td>
<td><bean:write name= book property= price /></td>
</tr>
</logic:present>
</logic:iterate>
</logic:present>
</table>
<logic:present name= page >
<logic:equal name= page property= hasNextPage value= true >
<:link page= /haha do?action=nextPage >nextPage</:link>
</logic:equal>
<logic:equal name= page property= hasPreviousPage value= true >
<:link page= /haha do?action=previousPage >previousPage</:link>
</logic:equal>
共分<bean:write name= page property= totalPages />页显示 当前是
<bean:write name= page property= currentPage />页
</logic:present>
</body>
</:>
这个是首页的JSP页面 只有一个连接 提交一个haha do的请求
<%@ taglib uri= /WEB INF/struts tld prefix= %>
<%@ page contentType= text/;charset=gb language= java %>
<:>
<head>
</head>
<body>
<:link action= haha do >GotoPage</:link>
</body>
</:>
struts下的分页代码
Struts分页的一个实现
在Web应用程序里 分页总让我们开发人员感到很头疼 倒不是因为技术上有多么困难 只是本来和业务没有太多关系的这么一个问题 你却得花不少功夫来处理 要是稍不留神 时不时出点问题就更郁闷了 我现在做的一个项目也到了该处理分页的时候了 感觉以前处理得都不好 所以这次有所改变 基本目标是在现有(未分页)的代码基础上 尽量少做修改 并且同样的代码可以应用于不同模块的分页 以下就是我用的方法
首先 考虑分页绝大多数发生在列表时 组合查询时也需要用到 在我的项目里 列表的Action一般名字为ListXXXActioin 例如客户列表是ListClientsAction等等 在未分页前 ListXXXAction里会把所有的对象取出 通过request setAttribute()放在request里 然后将请求转向到列表的jsp(例如listClients jsp)显示出来(你可能会说不要在Action里放业务逻辑 但现在这不是我们考虑的重点) 而分页后 我们只取用户请求页对应的那些对象 为了最大限度的达到代码重用 我做了以下工作
新建一个Pager类 该类有beginPage endPage currentPage pageSize和total等int类型的属性 分别代表开始页 结束页 当前页 每页记录数和总记录数 它主要是让jsp页面显示页导航使用的 请注意currentPage属性是从 开始的
新建一个AbstractListActioin类 并让所有ListXXXAction都继承它 在这个类里覆蓋execute()方法 可以在这里判断权限等等 并在判断权限通过后执行一个abstract的act()方法 这个act()由ListXXXAction来实现
在AbstractListAction里增加getPage()方法 用来从request得到用户请求的页码(若未请求则认为是第 页)
protected int getPage(HttpServletRequest request)
String p = request getParameter( p );
if (p == null)
return ;
else
try
return Integer parseInt(p);
catch (NumberFormatException e)
return ;
在AbstractListAction里增加makePager()方法 用来向request里增加一个Pager类的实例 供jsp页面显示页导航
protected Pager makePager(HttpServletRequest request int total)
Pager pager=new Pager();
pager setTotal(total);
pager setPageSize(Config getInstance() getPageSize());
pager setBeginPage( );
pager setEndPage(((pager getTotal()) ) / pager getPageSize() + );
pager setCurrentPage(getPage(request));
return pager;
注意在我的项目里 每页记录数是写在配置文件里的 如果你没有配置文件 上面第 行setPageSize()的参数直接填数字即可 例如pager setPageSize( );
这样 所有的ListXXXAction都可以使用getPage()得到请求的页码 并且能够方便的通过makePager()构造需要放在request里的pager对象了 现在要在从数据库取数据的代码上再做一些修改 即只取所需要的那一部分数据 由于我的项目中使用了Hibernate 所以这个修改也不是很困难 未分页前 在我的ListClientsAction里是通过构造一个Query来得到全部Client的 现在 只要在构造这个Query后再加两句(setMaxResults和setFirstResult)即可
Query query = ;//构造query的语句
int total = ;//得到总记录数
Pager pager = makePager(request total);//调用父类中的方法构造一个Pager实例
query setMaxResults(pager getPageSize());//设置每页记录数
query setFirstResult(pager getCurrentPage() * pager getPageSize()); //设置开始位置
request setAttribute(Pager class getName() pager);//把pager放在request里
request setAttribute(Client class getName() query list());
目前存在一个问题 就是在上面代码的第二句中 应该是获得总记录数 但我暂时没有特别好的办法不得到全部对象而直接得到记录数 只能很恐怖的用 int total = query list() size(); 汗……
最后 我写了一个页导航的jsp页面pager jsp 供各个显示列表的jsp来include 代码如下
<%Pager pager=(Pager)request getAttribute(Pager class getName());%>
<table width= % border= align= center cellpadding= cellspacing= bgcolor= #CCCCCC >
<tr>
<td bgcolor= #EEEEEE align= right >
<bean:message key= prompt pager arg = <%= +pager getTotal()%> />
[
<%
String url=request getRequestURL() toString();
for(int i=pager getBeginPage();i<pager getEndPage();i++)
if(i==pager getCurrentPage())
%>
<%=(i+ )%>
<%else
String qs=request getQueryString()==null? :request getQueryString();
String op = p= +pager getCurrentPage();//Original page parameter expression
String np = p= +i;//New expression
if(qs indexOf(op)== )
qs=np+ & +qs;
qs=qs replaceAll(op np);
%>
<a <%=url+ ? +qs%> ><%=(i+ )%></a>
<%%>
<%if(i<pager getEndPage() )%>
<%%>
<%%>
]
</td></tr>
</table>
我觉得有必要解释一下 在上面的代码中 关于每一页对应的url是这样处理 取request getRequestURL() toString()和request getQueryString() 其中前者是不需要变的 而后者中可能包含 q= 这样的页码请求也可能不包含即缺省请求第 页 所以统一用replaceAll()方法将其去掉 然后将对应的页码请求串(如 q= )加在qs的前面 这样做的好处是 每个模块都可以使用这个页导航 并且不会丢失url中的其他参数(例如今后加入排序功能后 url中可能包含 dir=desc 这样的参数)
在列表jsp(listClients jsp)中 很简单的这样include它(之所以要放在<logic:notEmpty>里 是希望在没有记录可显示的时候就不显示页导航了)
<logic:notEmpty name= <%=Client class getName()%> >
<%@include file= /pager jsp %>
</logic:notEmpty>
经过上面几步的处理 我的客户列表已经可以实现分页了 效果见下图 如果在另外一个模块中也需要分页 比如部门列表时 只需要 修改ListDeptsAction继承AbstractListAction 在ListDeptsAction里增加setMaxResults()和setFirstResults()方法 在listDepts jsp中适当的位置include页导航 就可以了 改动是相当小的
<%@ taglib uri= /WEB INF/struts logic tld prefix= logic %>
<%@ taglib uri= /WEB INF/struts bean tld prefix= bean %>
<%@ taglib uri= /WEB INF/struts tld prefix= %>
<%@ page contentType= text/; charset=gb language= java %>
<: locale= true >
<head>
<meta equiv= Content Type content= text/; charset=gb >
</head>
<body>
<table border= >
<tr><th>书名</th><th>作者</th><th>价格</th></tr>
<logic:present name= result >
<logic:iterate id= book name= result type= bean Book >
<logic:present name= book >
<tr>
<td><bean:write name= book property= bookname /></td>
<td> <bean:write name= book property= author /></td>
<td><bean:write name= book property= price /></td>
</tr>
</logic:present>
</logic:iterate>
</logic:present>
</table>
<logic:equal name= page property= hasNextPage value= true >
<:link page= /page do?action=nextPage >nextPage</:link>
</logic:equal>
<logic:equal name= page property= hasPreviousPage value= true >
<:link page= /page do?action=previousPage >PreviousPage</:link>
</logic:equal>
共有数据总数<bean:write name= page property= totalRows />;
共分<bean:write name= page property= totalPages />页 当前是第
<bean:write name= page property= currentPage />页
</body>
cha138/Article/program/Oracle/201311/17430相关参考
“俄罗斯存储过程”的改良版 CREATEprocedurepagination(@pagesizeint页面大小如每页存储条记录@pageindexint当前页码)assetnocountonb
SQL大数据量分页存储过程效率测试 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! /*存储过程分
SQLServer千万数量级分页存储过程 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 随着信息
项目接近尾声了感觉将业务逻辑放到oracle中使得后台代码很精简oracle很有搞头! PL\\SQL: createorreplaceprocedureproc_client_List客户多
oracle存储过程分页代码是怎么实现的我们来看下实验小编为您整理的方法吧! /*******存储过程分页代码**********/ 包头 createorreplacepackagepck
分页SQLServer存储过程 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! /*用存储过程实现
在看了众多的分页存储过程以后发现都是针对sqlserver的而没有oracle的因此想写一个关于oracle的存储过程因为我用到的数据库是oracleoracle分页存储过程的思路于sqlserv
createorreplacepackagemypack as typecursortestCursorisrefcursor; endmypack; tableName表名pageSiz
ASP.NET利用存储过程实现分页 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 首先说下思路写
ASP.NET存储过程自定义分页详解 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! &n