熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Oracle >> 正文

高效SQL分頁存儲過程(2)

2022-06-13   來源: Oracle 

  Book類負責查詢數據庫把結果放到一個ArrayList中

  package bean;

  import javasql*;

  import javautilArrayList;

  public class Book {

  private String bookname;

  private String author;

  private String price;

  public Book(String nameString authorString price) {

  thisbookname=name;

  thisauthor=author;

  thisprice=price;

  }

  public void setBookname(String bookname) {

  thisbookname=bookname;

  }

  public void setAuthor(String Author) {

  thisauthor=author;

  }

  public void setPrice(String price) {

  thisprice=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=sqselect(sql);

  while(resultSetnext()) {

  String name=resultSetgetString(name);

  String author=resultSetgetString(author);

  String price=resultSetgetString(price);

  Book book=new Book(nameauthorprice);

  arrayListadd(book);

  }

  resultSetclose();

  }

  catch(SQLException e)

  {

  Systemoutprintln(數據庫錯誤+etoString());

  }

  return arrayList;

  }

  }

  這個是SqlBook負責和數據庫建立一個連接的Bean

  package bean;

  import javasqlConnection;

  import javasqlDriverManager;

  import javasqlResultSet;

  import javasqlStatement;

  public class SqlBean {

  String url=jdbc:microsoft:sqlserver://localhost:;DatabaseName=eBookStore;

  Connection con=null;

  Statement sta=null;

  public SqlBean() {

  try

  {

  ClassforName(commicrosoftjdbcsqlserverSQLServerDriver);

  con=DriverManagergetConnection(urlsa);

  sta=concreateStatement();

  }

  catch(Exception e)

  {

  Systemoutprintln(連接錯誤+etoString());

  }

  }

  public ResultSet select(String selects) throws Exception

  {

  return staexecuteQuery(selects);

  }

  }

  …………………………………………………………………………

  這個是負責顯示分頁的JSP頁pagetestjsp

  <%@ taglib uri=/WEBINF/strutshtmltld prefix=html%>

  <%@ taglib uri=/WEBINF/strutsbeantld prefix=bean%>

  <%@ taglib uri=/WEBINF/strutslogictld prefix=logic%>

  <%@ page contentType=text/html;charset=gb%>

  <html:html 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=beanBook>

  <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>

  <html:link page=/hahado?action=nextPage>nextPage</html:link>

  </logic:equal>

  <logic:equal name=page property=hasPreviousPage value=true>

  <html:link page=/hahado?action=previousPage>previousPage</html:link>

  </logic:equal>

  共分<bean:write name=page property=totalPages/>頁顯示當前是

  <bean:write name=page property=currentPage/>頁

  </logic:present>

  </body>

  </html:html>

  這個是首頁的JSP頁面只有一個連接提交一個hahado的請求

  <%@ taglib uri=/WEBINF/strutshtmltld prefix=html%>

  <%@ page contentType=text/html;charset=gb language=java%>

  <html:html>

  <head>

  </head>

  <body>

  <html:link action=hahado>GotoPage</html:link>

  </body>

  </html:html>

  struts下的分頁代碼

  Struts分頁的一個實現

  在Web應用程序裡分頁總讓我們開發人員感到很頭疼倒不是因為技術上有多麼困難只是本來和業務沒有太多關系的這麼一個問題你卻得花不少功夫來處理要是稍不留神時不時出點問題就更郁悶了我現在做的一個項目也到了該處理分頁的時候了感覺以前處理得都不好所以這次有所改變基本目標是在現有(未分頁)的代碼基礎上盡量少做修改並且同樣的代碼可以應用於不同模塊的分頁以下就是我用的方法

  首先考慮分頁絕大多數發生在列表時組合查詢時也需要用到在我的項目裡列表的Action一般名字為ListXXXActioin例如客戶列表是ListClientsAction等等在未分頁前ListXXXAction裡會把所有的對象取出通過requestsetAttribute()放在request裡然後將請求轉向到列表的jsp(例如listClientsjsp)顯示出來(你可能會說不要在Action裡放業務邏輯但現在這不是我們考慮的重點)而分頁後我們只取用戶請求頁對應的那些對象為了最大限度的達到代碼重用我做了以下工作

  新建一個Pager類該類有beginPageendPagecurrentPagepageSize和total等int類型的屬性分別代表開始頁結束頁當前頁每頁記錄數和總記錄數它主要是讓jsp頁面顯示頁導航使用的請注意currentPage屬性是從開始的

  新建一個AbstractListActioin類並讓所有ListXXXAction都繼承它在這個類裡覆蓋execute()方法可以在這裡判斷權限等等並在判斷權限通過後執行一個abstract的act()方法這個act()由ListXXXAction來實現

  在AbstractListAction裡增加getPage()方法用來從request得到用戶請求的頁碼(若未請求則認為是第頁)

  protected   int   getPage(HttpServletRequest   request)   {

  String   p   =   requestgetParameter(p);

  if   (p   ==   null)

  return   ;

  else

  try   {

  return   IntegerparseInt(p);

  }   catch   (NumberFormatException   e)   {

  return   ;

  }

  }

  在AbstractListAction裡增加makePager()方法用來向request裡增加一個Pager類的實例供jsp頁面顯示頁導航

  protected   Pager   makePager(HttpServletRequest   request   int   total)   {

  Pager   pager=new   Pager();

  pagersetTotal(total);

  pagersetPageSize(ConfiggetInstance()getPageSize());

  pagersetBeginPage();

  pagersetEndPage(((pagergetTotal())      )   /   pagergetPageSize()   +   );

  pagersetCurrentPage(getPage(request));

  return   pager;

  }

  注意在我的項目裡每頁記錄數是寫在配置文件裡的如果你沒有配置文件上面第行setPageSize()的參數直接填數字即可例如pagersetPageSize();

  這樣所有的ListXXXAction都可以使用getPage()得到請求的頁碼並且能夠方便的通過makePager()構造需要放在request裡的pager對象了現在要在從數據庫取數據的代碼上再做一些修改即只取所需要的那一部分數據由於我的項目中使用了Hibernate所以這個修改也不是很困難未分頁前在我的ListClientsAction裡是通過構造一個Query來得到全部Client的現在只要在構造這個Query後再加兩句(setMaxResults和setFirstResult)即可

  Query   query   =     ;//構造query的語句

  int   total   =     ;//得到總記錄數

  Pager   pager   =   makePager(request   total);//調用父類中的方法構造一個Pager實例

  querysetMaxResults(pagergetPageSize());//設置每頁記錄數

  querysetFirstResult(pagergetCurrentPage()   *   pagergetPageSize());   //設置開始位置

  requestsetAttribute(PagerclassgetName()   pager);//把pager放在request裡

  requestsetAttribute(ClientclassgetName()   querylist());

  目前存在一個問題就是在上面代碼的第二句中應該是獲得總記錄數但我暫時沒有特別好的辦法不得到全部對象而直接得到記錄數只能很恐怖的用int   total   =   querylist()size();汗……

  最後我寫了一個頁導航的jsp頁面pagerjsp供各個顯示列表的jsp來include代碼如下

  <%Pager   pager=(Pager)requestgetAttribute(PagerclassgetName());%>

  <table   width=%   border=   align=center   cellpadding=   cellspacing=   bgcolor=#CCCCCC>

  <tr>

  <td   bgcolor=#EEEEEE   align=right>

  <bean:message   key=promptpager   arg=<%=+pagergetTotal()%>/>

  [

  <%

  String   url=requestgetRequestURL()toString();

  for(int   i=pagergetBeginPage();i<pagergetEndPage();i++){

  if(i==pagergetCurrentPage()){

  %>

  <%=(i+)%>

  <%}else{

  String   qs=requestgetQueryString()==null?:requestgetQueryString();

  String   op   =   p=+pagergetCurrentPage();//Original   page   parameter   expression

  String   np   =   p=+i;//New   expression

  if(qsindexOf(op)==)

  qs=np+&+qs;

  qs=qsreplaceAll(opnp);

  %>

  <a   <%=url+?+qs%>><%=(i+)%></a>

  <%}%>

  <%if(i<pagergetEndPage()){%>

  &nbsp;

  <%}%>

  <%}%>

  ]

  </td></tr>

  </table>

  我覺得有必要解釋一下在上面的代碼中關於每一頁對應的url是這樣處理取requestgetRequestURL()toString()和requestgetQueryString()其中前者是不需要變的而後者中可能包含q=這樣的頁碼請求也可能不包含即缺省請求第所以統一用replaceAll()方法將其去掉然後將對應的頁碼請求串(如q=)加在qs的前面這樣做的好處是每個模塊都可以使用這個頁導航並且不會丟失url中的其他參數(例如今後加入排序功能後url中可能包含dir=desc這樣的參數)

  在列表jsp(listClientsjsp)中很簡單的這樣include它(之所以要放在<logic:notEmpty>裡是希望在沒有記錄可顯示的時候就不顯示頁導航了)

  <logic:notEmpty   name=<%=ClientclassgetName()%>>

  <%@include   file=/pagerjsp%>

  </logic:notEmpty>

  經過上面幾步的處理我的客戶列表已經可以實現分頁了效果見下圖如果在另外一個模塊中也需要分頁比如部門列表時只需要修改ListDeptsAction繼承AbstractListAction在ListDeptsAction裡增加setMaxResults()和setFirstResults()方法在listDeptsjsp中適當的位置include頁導航就可以了改動是相當小的

  <%@   taglib   uri=/WEBINF/strutslogictld   prefix=logic   %>

  <%@   taglib   uri=/WEBINF/strutsbeantld   prefix=bean   %>

  <%@   taglib   uri=/WEBINF/strutshtmltld   prefix=html   %>

  <%@   page   contentType=text/html;   charset=gb   language=java%>

  <html:html   locale=true>

  <head>

  <meta   httpequiv=ContentType   content=text/html;   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=beanBook   >

  <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>

  <html:link   page=/pagedo?action=nextPage>nextPage</html:link>

  </logic:equal>

  <logic:equal   name=page   property=hasPreviousPage   value=true>

  <html:link   page=/pagedo?action=previousPage>PreviousPage</html:link>

  </logic:equal>

  共有數據總數<bean:write   name=page   property=totalRows/>;

  共分<bean:write   name=page   property=totalPages/>頁當前是第

  <bean:write   name=page   property=currentPage/>頁

  </body>

  </html:html>


From:http://tw.wingwit.com/Article/program/Oracle/201311/17430.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.