欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

JSP分頁(yè)技術(shù)實(shí)現(xiàn)

系統(tǒng) 1763 0
目前比較廣泛使用的分頁(yè)方式是將查詢結(jié)果緩存在HttpSession或有狀態(tài)bean中,翻頁(yè)的時(shí)候從緩存中取出一頁(yè)數(shù)據(jù)顯示。這種方法有兩個(gè)主要的缺點(diǎn):一是用戶可能看到的是過(guò)期數(shù)據(jù);二是如果數(shù)據(jù)量非常大時(shí)第一次查詢遍歷結(jié)果集會(huì)耗費(fèi)很長(zhǎng)時(shí)間,并且緩存的數(shù)據(jù)也會(huì)占用大量?jī)?nèi)存,效率明顯下降。
  其它常見(jiàn)的方法還有每次翻頁(yè)都查詢一次數(shù)據(jù)庫(kù),從ResultSet中只取出一頁(yè)數(shù)據(jù)(使用rs.last();rs.getRow()獲得總計(jì)錄條數(shù),使用rs.absolute()定位到本頁(yè)起始記錄)。這種方式在某些數(shù)據(jù)庫(kù)(如oracle)的JDBC實(shí)現(xiàn)中差不多也是需要遍歷所有記錄,實(shí)驗(yàn)證明在記錄數(shù)很大時(shí)速度非常慢。
  至于緩存結(jié)果集ResultSet的方法則完全是一種錯(cuò)誤的做法。因?yàn)镽esultSet在Statement或Connection關(guān)閉時(shí)也會(huì)被關(guān)閉,如果要使ResultSet有效勢(shì)必長(zhǎng)時(shí)間占用數(shù)據(jù)庫(kù)連接。

  因此比較好的分頁(yè)做法應(yīng)該是每次翻頁(yè)的時(shí)候只從數(shù)據(jù)庫(kù)里檢索頁(yè)面大小的塊區(qū)的數(shù)據(jù)。這樣雖然每次翻頁(yè)都需要查詢數(shù)據(jù)庫(kù),但查詢出的記錄數(shù)很少,網(wǎng)絡(luò)傳輸數(shù)據(jù)量不大,如果使用連接池更可以略過(guò)最耗時(shí)的建立數(shù)據(jù)庫(kù)連接過(guò)程。而在數(shù)據(jù)庫(kù)端有各種成熟的優(yōu)化技術(shù)用于提高查詢速度,比在應(yīng)用服務(wù)器層做緩存有效多了。

  在oracle數(shù)據(jù)庫(kù)中查詢結(jié)果的行號(hào)使用偽列ROWNUM表示(從1開(kāi)始)。例如select*fromemployeewhererownum<10返回前10條記錄。但因?yàn)閞ownum是在查詢之后排序之前賦值的,所以查詢employee按birthday排序的第100到120條記錄應(yīng)該這么寫:
    select*from(
    
selectmy_table.*,rownumasmy_rownumfrom(
selectname,birthdayfromemployeeorderbybirthday
)my_tablewhererownum<120
)wheremy_rownum>=100

  mySQL可以使用LIMIT子句:
    selectname,birthdayfromemployeeorderbybirthdayLIMIT99,20
  DB2有rownumber()函數(shù)用于獲取當(dāng)前行數(shù)。
  SQLServer沒(méi)研究過(guò),可以參考這篇文章: http://www.csdn.net/develop/article/18/18627.shtm

  在Web程序中分頁(yè)會(huì)被頻繁使用,但分頁(yè)的實(shí)現(xiàn)細(xì)節(jié)卻是編程過(guò)程中比較麻煩的事情。大多分頁(yè)顯示的查詢操作都同時(shí)需要處理復(fù)雜的多重查詢條件,sql語(yǔ)句需要?jiǎng)討B(tài)拼接組成,再加上分頁(yè)需要的記錄定位、總記錄條數(shù)查詢以及查詢結(jié)果的遍歷、封裝和顯示,程序會(huì)變得很復(fù)雜并且難以理解。因此需要一些工具類簡(jiǎn)化分頁(yè)代碼,使程序員專注于業(yè)務(wù)邏輯部分。下面是我設(shè)計(jì)的兩個(gè)工具類:
PagedStatement 封裝了數(shù)據(jù)庫(kù)連接、總記錄數(shù)查詢、分頁(yè)查詢、結(jié)果數(shù)據(jù)封裝和關(guān)閉數(shù)據(jù)庫(kù)連接等操作,并使用了PreparedStatement支持動(dòng)態(tài)設(shè)置參數(shù)。
RowSetPage 參考PetStore的pagebypageiterator模式,設(shè)計(jì)RowSetPage用于封裝查詢結(jié)果(使用OracleCachedRowSet緩存查詢出的一頁(yè)數(shù)據(jù),關(guān)于使用CachedRowSet封裝數(shù)據(jù)庫(kù)查詢結(jié)果請(qǐng)參考 JSP頁(yè)面查詢顯示常用模式 )以及當(dāng)前頁(yè)碼、總記錄條數(shù)、當(dāng)前記錄數(shù)等信息,并且可以生成簡(jiǎn)單的HTML分頁(yè)代碼。
  PagedStatement查詢的結(jié)果封裝成RowsetPage。

  下面是簡(jiǎn)單的 使用示例
  1. //DAO查詢數(shù)據(jù)部分代碼:
  2. public RowSetPagegetEmployee( String gender, int pageNo) throws Exception {
  3. String sql="selectemp_id,emp_code,user_name,real_namefromemployeewheregender=?";
  4. //使用Oracle數(shù)據(jù)庫(kù)的分頁(yè)查詢實(shí)現(xiàn),每頁(yè)顯示5條
  5. PagedStatementpst= new PagedStatementOracleImpl(sql,pageNo,5);
  6. pst.setString(1,gender);
  7. return pst.executeQuery();
  8. }
  9. //Servlet處理查詢請(qǐng)求部分代碼:
  10. int pageNo;
  11. try {
  12. //可以通過(guò)參數(shù)pageno獲得用戶選擇的頁(yè)碼
  13. pageNo= Integer .parseInt(request.getParameter("pageno"));
  14. } catch ( Exception ex){
  15. //默認(rèn)為第一頁(yè)
  16. pageNo=1;
  17. }
  18. String gender=request.getParameter("gender");
  19. request.setAttribute("empPage",myBean.getEmployee(gender,pageNo));
  20. //JSP顯示部分代碼
  21. <%@page import ="page.RowSetPage"%>
  22. <scriptlanguage="javascript">
  23. functiondoQuery(){
  24. form1.actionType.value="doQuery";
  25. form1.submit();
  26. }
  27. </script>
  28. <formname=form1method=get>
  29. <inputtype=hiddenname=actionType>
  30. 性別:
  31. <inputtype=textname=gendersize=1value="<%=request.getParameter("gender")%>">
  32. <inputtype=buttonvalue="查詢"onclick="doQuery()">
  33. <%
  34. RowSetPageempPage=(RowSetPage)request.getAttribute("empPage");
  35. if (empPage== null )empPage=RowSetPage.EMPTY_PAGE;
  36. %>
  37. <tablecellspacing="0"width="90%">
  38. <tr><td>ID</td><td>代碼</td><td>用戶名</td><td>姓名</td></tr>
  39. <%
  40. javax.sql. RowSet empRS=(javax.sql. RowSet )empPage.getRowSet();
  41. if (empRS!= null ) while (empRS.next()){
  42. %>
  43. <tr>
  44. <td><%=empRS.getString("EMP_ID")%></td>
  45. <td><%=empRS.getString("EMP_CODE")%></td>
  46. <td><%=empRS.getString("USER_NAME")%></td>
  47. <td><%=empRS.getString("REAL_NAME")%></td>
  48. </tr>
  49. <%
  50. } //endwhile
  51. %>
  52. <tr>
  53. <%
  54. //顯示總頁(yè)數(shù)和當(dāng)前頁(yè)數(shù)(pageno)以及分頁(yè)代碼。
  55. //此處doQuery為頁(yè)面上提交查詢動(dòng)作的javascript函數(shù)名,pageno為標(biāo)識(shí)當(dāng)前頁(yè)碼的參數(shù)名
  56. %>
  57. <tdcolspan=4><%=empPage.getHTML("doQuery","pageno")%></td>
  58. </tr>
  59. </table>
  60. </form>

  效果如圖:


  因?yàn)榉猪?yè)顯示一般都會(huì)伴有查詢條件和查詢動(dòng)作,頁(yè)面應(yīng)已經(jīng)有校驗(yàn)查詢條件和提交查詢的javascript方法(如上面的doQuery),所以RowSetPage.getHTML()生成的分頁(yè)代碼在用戶選擇新頁(yè)碼時(shí)直接回調(diào)前面的處理提交查詢的javascript方法。注意在顯示查詢結(jié)果的時(shí)候上次的查詢條件也需要保持,如<inputtype=textname=gendersize=1value="<%=request.getParameter("gender")%>">。同時(shí)由于頁(yè)碼的參數(shù)名可以指定,因此也支持在同一頁(yè)面中有多個(gè)分頁(yè)區(qū)。
  另一種分頁(yè)代碼實(shí)現(xiàn)是生成每一頁(yè)的URL,將查詢參數(shù)和頁(yè)碼作為QueryString附在URL后面。這種方法的缺陷是在查詢條件比較復(fù)雜時(shí)難以處理,并且需要指定處理查詢動(dòng)作的servlet,可能不適合某些定制的查詢操作。
  如果對(duì)RowSetPage.getHTML()生成的默認(rèn)分頁(yè)代碼不滿意可以編寫自己的分頁(yè)處理代碼,RowSetPage提供了很多getter方法用于獲取相關(guān)信息(如當(dāng)前頁(yè)碼、總頁(yè)數(shù)、總記錄數(shù)和當(dāng)前記錄數(shù)等)。
  在實(shí)際應(yīng)用中可以將分頁(yè)查詢和顯示做成jsptaglib,進(jìn)一步簡(jiǎn)化JSP代碼,屏蔽JavaCode。

附:分頁(yè)工具類的源代碼,有注釋,應(yīng)該很容易理解。

1.Page.java
2.RowSetPage.java(RowSetPage繼承Page)
3.PagedStatement.java
4.PagedStatementOracleImpl.java(PagedStatementOracleImpl繼承PagedStatement)



您可以任意使用這些源代碼,但必須保留authorevan_zhao@hotmail.com字樣
  1. ///////////////////////////////////
  2. //
  3. //Page.java
  4. //author:evan_zhao@hotmail.com
  5. //
  6. ///////////////////////////////////
  7. package page;
  8. import java.util. List ;
  9. import java.util. ArrayList ;
  10. import java.util. Collection ;
  11. import java.util. Collections ;
  12. /**
  13. *Title:分頁(yè)對(duì)象<br>
  14. *Description:用于包含數(shù)據(jù)及分頁(yè)信息的對(duì)象<br>
  15. *Page類實(shí)現(xiàn)了用于顯示分頁(yè)信息的基本方法,但未指定所含數(shù)據(jù)的類型,
  16. *可根據(jù)需要實(shí)現(xiàn)以特定方式組織數(shù)據(jù)的子類,<br>
  17. *如RowSetPage以RowSet封裝數(shù)據(jù),ListPage以List封裝數(shù)據(jù)<br>
  18. *Copyright:Copyright(c)2002<br>
  19. *@authorevan_zhao@hotmail.com<br>
  20. *@version1.0
  21. */
  22. public class Page implements java.io. Serializable {
  23. public static final PageEMPTY_PAGE= new Page();
  24. public static final int DEFAULT_PAGE_SIZE=20;
  25. public static final int MAX_PAGE_SIZE=9999;
  26. private int myPageSize=DEFAULT_PAGE_SIZE;
  27. private int start;
  28. private int avaCount,totalSize;
  29. private Object data;
  30. private int currentPageno;
  31. private int totalPageCount;
  32. /**
  33. *默認(rèn)構(gòu)造方法,只構(gòu)造空頁(yè)
  34. */
  35. protected Page(){
  36. this .init(0,0,0,DEFAULT_PAGE_SIZE, new Object ());
  37. }
  38. /**
  39. *分頁(yè)數(shù)據(jù)初始方法,由子類調(diào)用
  40. *@paramstart本頁(yè)數(shù)據(jù)在數(shù)據(jù)庫(kù)中的起始位置
  41. *@paramavaCount本頁(yè)包含的數(shù)據(jù)條數(shù)
  42. *@paramtotalSize數(shù)據(jù)庫(kù)中總記錄條數(shù)
  43. *@parampageSize本頁(yè)容量
  44. *@paramdata本頁(yè)包含的數(shù)據(jù)
  45. */
  46. protected void init( int start, int avaCount, int totalSize, int pageSize, Object data){
  47. this .avaCount=avaCount;
  48. this .myPageSize=pageSize;
  49. this .start=start;
  50. this .totalSize=totalSize;
  51. this .data=data;
  52. //System.out.println("avaCount:"+avaCount);
  53. //System.out.println("totalSize:"+totalSize);
  54. if (avaCount>totalSize){
  55. //thrownewRuntimeException("記錄條數(shù)大于總條數(shù)?!");
  56. }
  57. this .currentPageno=(start-1)/pageSize+1;
  58. this .totalPageCount=(totalSize+pageSize-1)/pageSize;
  59. if (totalSize==0&&avaCount==0){
  60. this .currentPageno=1;
  61. this .totalPageCount=1;
  62. }
  63. //System.out.println("StartIndextoPageNo:"+start+"-"+currentPageno);
  64. }
  65. public Object getData(){
  66. return this .data;
  67. }
  68. /**
  69. *取本頁(yè)數(shù)據(jù)容量(本頁(yè)能包含的記錄數(shù))
  70. *@return本頁(yè)能包含的記錄數(shù)
  71. */
  72. public int getPageSize(){
  73. return this .myPageSize;
  74. }
  75. /**
  76. *是否有下一頁(yè)
  77. *@return是否有下一頁(yè)
  78. */
  79. public boolean hasNextPage(){
  80. /*
  81. if(avaCount==0&&totalSize==0){
  82. returnfalse;
  83. }
  84. return(start+avaCount-1)<totalSize;
  85. */
  86. return ( this .getCurrentPageNo()< this .getTotalPageCount());
  87. }
  88. /**
  89. *是否有上一頁(yè)
  90. *@return是否有上一頁(yè)
  91. */
  92. public boolean hasPreviousPage(){
  93. /*
  94. returnstart>1;
  95. */
  96. return ( this .getCurrentPageNo()>1);
  97. }
  98. /**
  99. *獲取當(dāng)前頁(yè)第一條數(shù)據(jù)在數(shù)據(jù)庫(kù)中的位置
  100. *@return
  101. */
  102. public int getStart(){
  103. return start;
  104. }
  105. /**
  106. *獲取當(dāng)前頁(yè)最后一條數(shù)據(jù)在數(shù)據(jù)庫(kù)中的位置
  107. *@return
  108. */
  109. public int getEnd(){
  110. int end= this .getStart()+ this .getSize()-1;
  111. if (end<0){
  112. end=0;
  113. }
  114. return end;
  115. }
  116. /**
  117. *獲取上一頁(yè)第一條數(shù)據(jù)在數(shù)據(jù)庫(kù)中的位置
  118. *@return記錄對(duì)應(yīng)的rownum
  119. */
  120. public int getStartOfPreviousPage(){
  121. return Math .max(start-myPageSize,1);
  122. }
  123. /**
  124. *獲取下一頁(yè)第一條數(shù)據(jù)在數(shù)據(jù)庫(kù)中的位置
  125. *@return記錄對(duì)應(yīng)的rownum
  126. */
  127. public int getStartOfNextPage(){
  128. return start+avaCount;
  129. }
  130. /**
  131. *獲取任一頁(yè)第一條數(shù)據(jù)在數(shù)據(jù)庫(kù)中的位置,每頁(yè)條數(shù)使用默認(rèn)值
  132. *@parampageNo頁(yè)號(hào)
  133. *@return記錄對(duì)應(yīng)的rownum
  134. */
  135. public static int getStartOfAnyPage( int pageNo){
  136. return getStartOfAnyPage(pageNo,DEFAULT_PAGE_SIZE);
  137. }
  138. /**
  139. *獲取任一頁(yè)第一條數(shù)據(jù)在數(shù)據(jù)庫(kù)中的位置
  140. *@parampageNo頁(yè)號(hào)
  141. *@parampageSize每頁(yè)包含的記錄數(shù)
  142. *@return記錄對(duì)應(yīng)的rownum
  143. */
  144. public static int getStartOfAnyPage( int pageNo, int pageSize){
  145. int startIndex=(pageNo-1)*pageSize+1;
  146. if (startIndex<1)startIndex=1;
  147. //System.out.println("PageNotoStartIndex:"+pageNo+"-"+startIndex);
  148. return startIndex;
  149. }
  150. /**
  151. *取本頁(yè)包含的記錄數(shù)
  152. *@return本頁(yè)包含的記錄數(shù)
  153. */
  154. public int getSize(){
  155. return avaCount;
  156. }
  157. /**
  158. *取數(shù)據(jù)庫(kù)中包含的總記錄數(shù)
  159. *@return數(shù)據(jù)庫(kù)中包含的總記錄數(shù)
  160. */
  161. public int getTotalSize(){
  162. return this .totalSize;
  163. }
  164. /**
  165. *取當(dāng)前頁(yè)碼
  166. *@return當(dāng)前頁(yè)碼
  167. */
  168. public int getCurrentPageNo(){
  169. return this .currentPageno;
  170. }
  171. /**
  172. *取總頁(yè)碼
  173. *@return總頁(yè)碼
  174. */
  175. public int getTotalPageCount(){
  176. return this .totalPageCount;
  177. }
  178. /**
  179. *
  180. *@paramqueryJSFunctionName實(shí)現(xiàn)分頁(yè)的JS腳本名字,頁(yè)碼變動(dòng)時(shí)會(huì)自動(dòng)回調(diào)該方法
  181. *@parampageNoParamName頁(yè)碼參數(shù)名稱
  182. *@return
  183. */
  184. public String getHTML( String queryJSFunctionName, String pageNoParamName){
  185. if (getTotalPageCount()<1){
  186. return "<inputtype='hidden'name='"+pageNoParamName+"'value='1'>";
  187. }
  188. if (queryJSFunctionName== null ||queryJSFunctionName.trim(). length ()<1){
  189. queryJSFunctionName="gotoPage";
  190. }
  191. if (pageNoParamName== null ||pageNoParamName.trim(). length ()<1){
  192. pageNoParamName="pageno";
  193. }
  194. String gotoPage="_"+queryJSFunctionName;
  195. StringBuffer html= new StringBuffer ("/n");
  196. html.append("<scriptlanguage=/"Javascript1.2/">/n")
  197. .append("function").append(gotoPage).append("(pageNo){/n")
  198. .append("varcurPage=1;/n")
  199. .append("try{curPage=document.all[/"")
  200. .append(pageNoParamName).append("/"].value;/n")
  201. .append("document.all[/"").append(pageNoParamName)
  202. .append("/"].value=pageNo;/n")
  203. .append("").append(queryJSFunctionName).append("(pageNo);/n")
  204. .append("returntrue;/n")
  205. .append("}catch(e){/n")
  206. //.append("try{/n")
  207. //.append("document.forms[0].submit();/n")
  208. //.append("}catch(e){/n")
  209. .append("alert('尚未定義查詢方法:function")
  210. .append(queryJSFunctionName).append("()');/n")
  211. .append("document.all[/"").append(pageNoParamName)
  212. .append("/"].value=curPage;/n")
  213. .append("returnfalse;/n")
  214. //.append("}/n")
  215. .append("}/n")
  216. .append("}")
  217. .append("</script>/n")
  218. .append("");
  219. html.append("<tableborder=0cellspacing=0cellpadding=0align=centerwidth=80%>/n")
  220. .append("<tr>/n")
  221. .append("<tdalign=left><br>/n");
  222. html.append("共").append(getTotalPageCount()).append("頁(yè)")
  223. .append("[").append(getStart()).append("..").append(getEnd())
  224. .append("/").append( this .getTotalSize()).append("]/n")
  225. .append("</td>/n")
  226. .append("<tdalign=right>/n");
  227. if (hasPreviousPage()){
  228. html.append("[<ahref='javascript:").append(gotoPage)
  229. .append("(").append(getCurrentPageNo()-1)
  230. .append(")'>上一頁(yè)</a>]/n");
  231. }
  232. html.append("第")
  233. .append("<selectname='")
  234. .append(pageNoParamName).append("'onChange='javascript:")
  235. .append(gotoPage).append("(this.value)'>/n");
  236. String selected="selected";
  237. for ( int i=1;i<=getTotalPageCount();i++){
  238. if (i==getCurrentPageNo())
  239. selected="selected";
  240. else selected="";
  241. html.append("<optionvalue='").append(i).append("'")
  242. .append(selected).append(">").append(i).append("</option>/n");
  243. }
  244. if (getCurrentPageNo()>getTotalPageCount()){
  245. html.append("<optionvalue='").append(getCurrentPageNo())
  246. .append("'selected>").append(getCurrentPageNo())
  247. .append("</option>/n");
  248. }
  249. html.append("</select>頁(yè)/n");
  250. if (hasNextPage()){
  251. html.append("[<ahref='javascript:").append(gotoPage)
  252. .append("(").append((getCurrentPageNo()+1))
  253. .append(")'>下一頁(yè)</a>]/n");
  254. }
  255. html.append("</td></tr></table>/n");
  256. return html.toString();
  257. }
  258. }
  259. ///////////////////////////////////
  260. //
  261. //RowSetPage.java
  262. //author:evan_zhao@hotmail.com
  263. //
  264. ///////////////////////////////////
  265. package page;
  266. import javax.sql. RowSet ;
  267. /**
  268. *<p>Title:RowSetPage</p>
  269. *<p>Description:使用RowSet封裝數(shù)據(jù)的分頁(yè)對(duì)象</p>
  270. *<p>Copyright:Copyright(c)2003</p>
  271. *@authorevan_zhao@hotmail.com
  272. *@version1.0
  273. */
  274. public class RowSetPage extends Page{
  275. private javax.sql. RowSet rs;
  276. /**
  277. *空頁(yè)
  278. */
  279. public static final RowSetPageEMPTY_PAGE= new RowSetPage();
  280. /**
  281. *默認(rèn)構(gòu)造方法,創(chuàng)建空頁(yè)
  282. */
  283. public RowSetPage(){
  284. this ( null ,0,0);
  285. }
  286. /**
  287. *構(gòu)造分頁(yè)對(duì)象
  288. *@paramcrs包含一頁(yè)數(shù)據(jù)的OracleCachedRowSet
  289. *@paramstart該頁(yè)數(shù)據(jù)在數(shù)據(jù)庫(kù)中的起始位置
  290. *@paramtotalSize數(shù)據(jù)庫(kù)中包含的記錄總數(shù)
  291. */
  292. public RowSetPage( RowSet crs, int start, int totalSize){
  293. this (crs,start,totalSize,Page.DEFAULT_PAGE_SIZE);
  294. }
  295. /**
  296. *構(gòu)造分頁(yè)對(duì)象
  297. *@paramcrs包含一頁(yè)數(shù)據(jù)的OracleCachedRowSet
  298. *@paramstart該頁(yè)數(shù)據(jù)在數(shù)據(jù)庫(kù)中的起始位置
  299. *@paramtotalSize數(shù)據(jù)庫(kù)中包含的記錄總數(shù)
  300. *@pageSize本頁(yè)能容納的記錄數(shù)
  301. */
  302. public RowSetPage( RowSet crs, int start, int totalSize, int pageSize){
  303. try {
  304. int avaCount=0;
  305. if (crs!= null ){
  306. crs.beforeFirst();
  307. if (crs.next()){
  308. crs.last();
  309. avaCount=crs.getRow();
  310. }
  311. crs.beforeFirst();
  312. }
  313. rs=crs;
  314. super .init(start,avaCount,totalSize,pageSize,rs);
  315. } catch (java.sql. SQLException sqle){
  316. throw new RuntimeException (sqle.toString());
  317. }
  318. }
  319. /**
  320. *取分頁(yè)對(duì)象中的記錄數(shù)據(jù)
  321. */
  322. public javax.sql. RowSet getRowSet(){
  323. return rs;
  324. }
  325. }
  326. ///////////////////////////////////
  327. //
  328. //PagedStatement.java
  329. //author:evan_zhao@hotmail.com
  330. //
  331. ///////////////////////////////////
  332. package page;
  333. import foo.DBUtil;
  334. import java.math. BigDecimal ;
  335. import java.util. List ;
  336. import java.util. Iterator ;
  337. import java.util. Collections ;
  338. import java.sql. Connection ;
  339. import java.sql. SQLException ;
  340. import java.sql. ResultSet ;
  341. import java.sql. Statement ;
  342. import java.sql. PreparedStatement ;
  343. import java.sql. Timestamp ;
  344. import javax.sql. RowSet ;
  345. /**
  346. *<p>Title:分頁(yè)查詢</p>
  347. *<p>Description:根據(jù)查詢語(yǔ)句和頁(yè)碼查詢出當(dāng)頁(yè)數(shù)據(jù)</p>
  348. *<p>Copyright:Copyright(c)2002</p>
  349. *@authorevan_zhao@hotmail.com
  350. *@version1.0
  351. */
  352. public abstract class PagedStatement{
  353. public final static int MAX_PAGE_SIZE=Page.MAX_PAGE_SIZE;
  354. protected String countSQL,querySQL;
  355. protected int pageNo,pageSize,startIndex,totalCount;
  356. protected javax.sql. RowSet rowSet;
  357. protected RowSetPagerowSetPage;
  358. private List boundParams;
  359. /**
  360. *構(gòu)造一查詢出所有數(shù)據(jù)的PageStatement
  361. *@paramsqlquerysql
  362. */
  363. public PagedStatement( String sql){
  364. this (sql,1,MAX_PAGE_SIZE);
  365. }
  366. /**
  367. *構(gòu)造一查詢出當(dāng)頁(yè)數(shù)據(jù)的PageStatement
  368. *@paramsqlquerysql
  369. *@parampageNo頁(yè)碼
  370. */
  371. public PagedStatement( String sql, int pageNo){
  372. this (sql,pageNo,Page.DEFAULT_PAGE_SIZE);
  373. }
  374. /**
  375. *構(gòu)造一查詢出當(dāng)頁(yè)數(shù)據(jù)的PageStatement,并指定每頁(yè)顯示記錄條數(shù)
  376. *@paramsqlquerysql
  377. *@parampageNo頁(yè)碼
  378. *@parampageSize每頁(yè)容量
  379. */
  380. public PagedStatement( String sql, int pageNo, int pageSize){
  381. this .pageNo=pageNo;
  382. this .pageSize=pageSize;
  383. this .startIndex=Page.getStartOfAnyPage(pageNo,pageSize);
  384. this .boundParams= Collections .synchronizedList( new java.util. LinkedList ());
  385. this .countSQL="selectcount(*)from("+sql+")";
  386. this .querySQL=intiQuerySQL(sql, this .startIndex,pageSize);
  387. }
  388. /**
  389. *生成查詢一頁(yè)數(shù)據(jù)的sql語(yǔ)句
  390. *@paramsql原查詢語(yǔ)句
  391. *@startIndex開(kāi)始記錄位置
  392. *@size需要獲取的記錄數(shù)
  393. */
  394. protected abstract String intiQuerySQL( String sql, int startIndex, int size);
  395. /**
  396. *使用給出的對(duì)象設(shè)置指定參數(shù)的值
  397. *@paramindex第一個(gè)參數(shù)為1,第二個(gè)為2,。。。
  398. *@paramobj包含參數(shù)值的對(duì)象
  399. */
  400. public void setObject( int index, Object obj) throws SQLException {
  401. BoundParambp= new BoundParam(index,obj);
  402. boundParams.remove(bp);
  403. boundParams.add(bp);
  404. }
  405. /**
  406. *使用給出的對(duì)象設(shè)置指定參數(shù)的值
  407. *@paramindex第一個(gè)參數(shù)為1,第二個(gè)為2,。。。
  408. *@paramobj包含參數(shù)值的對(duì)象
  409. *@paramtargetSqlType參數(shù)的數(shù)據(jù)庫(kù)類型
  410. */
  411. public void setObject( int index, Object obj, int targetSqlType) throws SQLException {
  412. BoundParambp= new BoundParam(index,obj,targetSqlType);
  413. boundParams.remove(bp);
  414. boundParams.add(bp);
  415. }
  416. /**
  417. *使用給出的對(duì)象設(shè)置指定參數(shù)的值
  418. *@paramindex第一個(gè)參數(shù)為1,第二個(gè)為2,。。。
  419. *@paramobj包含參數(shù)值的對(duì)象
  420. *@paramtargetSqlType參數(shù)的數(shù)據(jù)庫(kù)類型(常量定義在java.sql.Types中)
  421. *@paramscale精度,小數(shù)點(diǎn)后的位數(shù)
  422. *(只對(duì)targetSqlType是Types.NUMBER或Types.DECIMAL有效,其它類型則忽略)
  423. */
  424. public void setObject( int index, Object obj, int targetSqlType, int scale) throws SQLException {
  425. BoundParambp= new BoundParam(index,obj,targetSqlType,scale);
  426. boundParams.remove(bp);
  427. boundParams.add(bp);
  428. }
  429. /**
  430. *使用給出的字符串設(shè)置指定參數(shù)的值
  431. *@paramindex第一個(gè)參數(shù)為1,第二個(gè)為2,。。。
  432. *@paramstr包含參數(shù)值的字符串
  433. */
  434. public void setString( int index, String str) throws SQLException {
  435. BoundParambp= new BoundParam(index,str);
  436. boundParams.remove(bp);
  437. boundParams.add(bp);
  438. }
  439. /**
  440. *使用給出的字符串設(shè)置指定參數(shù)的值
  441. *@paramindex第一個(gè)參數(shù)為1,第二個(gè)為2,。。。
  442. *@paramtimestamp包含參數(shù)值的時(shí)間戳
  443. */
  444. public void setTimestamp( int index, Timestamp timestamp) throws SQLException {
  445. BoundParambp= new BoundParam(index,timestamp);
  446. boundParams.remove(bp);
  447. boundParams.add(bp);
  448. }
  449. /**
  450. *使用給出的整數(shù)設(shè)置指定參數(shù)的值
  451. *@paramindex第一個(gè)參數(shù)為1,第二個(gè)為2,。。。
  452. *@paramvalue包含參數(shù)值的整數(shù)
  453. */
  454. public void setInt( int index, int value) throws SQLException {
  455. BoundParambp= new BoundParam(index, new Integer (value));
  456. boundParams.remove(bp);
  457. boundParams.add(bp);
  458. }
  459. /**
  460. *使用給出的長(zhǎng)整數(shù)設(shè)置指定參數(shù)的值
  461. *@paramindex第一個(gè)參數(shù)為1,第二個(gè)為2,。。。
  462. *@paramvalue包含參數(shù)值的長(zhǎng)整數(shù)
  463. */
  464. public void setLong( int index, long value) throws SQLException {
  465. BoundParambp= new BoundParam(index, new Long (value));
  466. boundParams.remove(bp);
  467. boundParams.add(bp);
  468. }
  469. /**
  470. *使用給出的雙精度浮點(diǎn)數(shù)設(shè)置指定參數(shù)的值
  471. *@paramindex第一個(gè)參數(shù)為1,第二個(gè)為2,。。。
  472. *@paramvalue包含參數(shù)值的雙精度浮點(diǎn)數(shù)
  473. */
  474. public void setDouble( int index, double value) throws SQLException {
  475. BoundParambp= new BoundParam(index, new Double (value));
  476. boundParams.remove(bp);
  477. boundParams.add(bp);
  478. }
  479. /**
  480. *使用給出的BigDecimal設(shè)置指定參數(shù)的值
  481. *@paramindex第一個(gè)參數(shù)為1,第二個(gè)為2,。。。
  482. *@parambd包含參數(shù)值的BigDecimal
  483. */
  484. public void setBigDecimal( int index, BigDecimal bd) throws SQLException {
  485. BoundParambp= new BoundParam(index,bd);
  486. boundParams.remove(bp);
  487. boundParams.add(bp);
  488. }
  489. private void setParams( PreparedStatement pst) throws SQLException {
  490. if (pst== null || this .boundParams== null || this .boundParams.size()==0) return ;
  491. BoundParamparam;
  492. for ( Iterator itr= this .boundParams.iterator();itr.hasNext();){
  493. param=(BoundParam)itr.next();
  494. if (param== null ) continue ;
  495. if (param.sqlType==java.sql. Types .OTHER){
  496. pst.setObject(param.index,param.value);
  497. } else {
  498. pst.setObject(param.index,param.value,param.sqlType,param.scale);
  499. }
  500. }
  501. }
  502. /**
  503. *執(zhí)行查詢?nèi)〉靡豁?yè)數(shù)據(jù),執(zhí)行結(jié)束后關(guān)閉數(shù)據(jù)庫(kù)連接
  504. *@returnRowSetPage
  505. *@throwsSQLException
  506. */
  507. public RowSetPageexecuteQuery() throws SQLException {
  508. System .out.println("executeQueryUsingPreparedStatement");
  509. Connection conn=DBUtil.getConnection();
  510. PreparedStatement pst= null ;
  511. ResultSet rs= null ;
  512. try {
  513. pst=conn.prepareStatement( this .countSQL);
  514. setParams(pst);
  515. rs=pst.executeQuery();
  516. if (rs.next()){
  517. totalCount=rs.getInt(1);
  518. } else {
  519. totalCount=0;
  520. }
  521. rs.close();
  522. pst.close();
  523. if (totalCount<1) return RowSetPage.EMPTY_PAGE;
  524. pst=conn.prepareStatement( this .querySQL);
  525. System .out.println(querySQL);
  526. pst.setFetchSize( this .pageSize);
  527. setParams(pst);
  528. rs=pst.executeQuery();
  529. //rs.setFetchSize(pageSize);
  530. this .rowSet=populate(rs);
  531. rs.close();
  532. rs= null ;
  533. pst.close();
  534. pst= null ;
  535. this .rowSetPage= new RowSetPage( this .rowSet,startIndex,totalCount,pageSize);
  536. return this .rowSetPage;
  537. } catch ( SQLException sqle){
  538. //System.out.println("executeQuerySQLException");
  539. sqle.printStackTrace();
  540. throw sqle;
  541. } catch ( Exception e){
  542. e.printStackTrace();
  543. throw new RuntimeException (e.toString());
  544. } finally {
  545. //System.out.println("executeQueryfinally");
  546. DBUtil.close(rs,pst,conn);
  547. }
  548. }
  549. /**
  550. *將ResultSet數(shù)據(jù)填充進(jìn)CachedRowSet
  551. */
  552. protected abstract RowSet populate( ResultSet rs) throws SQLException ;
  553. /**
  554. *取封裝成RowSet查詢結(jié)果
  555. *@returnRowSet
  556. */
  557. public javax.sql. RowSet getRowSet(){
  558. return this .rowSet;
  559. }
  560. /**
  561. *取封裝成RowSetPage的查詢結(jié)果
  562. *@returnRowSetPage
  563. */
  564. public RowSetPagegetRowSetPage(){
  565. return this .rowSetPage;
  566. }
  567. /**
  568. *關(guān)閉數(shù)據(jù)庫(kù)連接
  569. */
  570. public void close(){
  571. //因?yàn)閿?shù)據(jù)庫(kù)連接在查詢結(jié)束或發(fā)生異常時(shí)即關(guān)閉,此處不做任何事情
  572. //留待擴(kuò)充。
  573. }
  574. private class BoundParam{
  575. int index;
  576. Object value;
  577. int sqlType;
  578. int scale;
  579. public BoundParam( int index, Object value){
  580. this (index,value,java.sql. Types .OTHER);
  581. }
  582. public BoundParam( int index, Object value, int sqlType){
  583. this (index,value,sqlType,0);
  584. }
  585. public BoundParam( int index, Object value, int sqlType, int scale){
  586. this .index=index;
  587. this .value=value;
  588. this .sqlType=sqlType;
  589. this .scale=scale;
  590. }
  591. public boolean equals( Object obj){
  592. if (obj!= null && this .getClass().isInstance(obj)){
  593. BoundParambp=(BoundParam)obj;
  594. if ( this .index==bp.index) return true ;
  595. }
  596. return false ;
  597. }
  598. }
  599. }
  600. ///////////////////////////////////
  601. //
  602. //PagedStatementOracleImpl.java
  603. //author:evan_zhao@hotmail.com
  604. //
  605. ///////////////////////////////////
  606. package page;
  607. import java.sql. ResultSet ;
  608. import java.sql. SQLException ;
  609. import javax.sql. RowSet ;
  610. import oracle.jdbc.rowset.OracleCachedRowSet;
  611. /**
  612. *<p>Title:分頁(yè)查詢Oracle數(shù)據(jù)庫(kù)實(shí)現(xiàn)</p>
  613. *<p>Copyright:Copyright(c)2002</p>
  614. *@authorevan_zhao@hotmail.com
  615. *@version1.0
  616. */
  617. public class PagedStatementOracleImpl extends PagedStatement{
  618. /**
  619. *構(gòu)造一查詢出所有數(shù)據(jù)的PageStatement
  620. *@paramsqlquerysql
  621. */
  622. public PagedStatementOracleImpl( String sql){
  623. super (sql);
  624. }
  625. /**
  626. *構(gòu)造一查詢出當(dāng)頁(yè)數(shù)據(jù)的PageStatement
  627. *@paramsqlquerysql
  628. *@parampageNo頁(yè)碼
  629. */
  630. public PagedStatementOracleImpl( String sql, int pageNo){
  631. super (sql,pageNo);
  632. }
  633. /**
  634. *構(gòu)造一查詢出當(dāng)頁(yè)數(shù)據(jù)的PageStatement,并指定每頁(yè)顯示記錄條數(shù)
  635. *@paramsqlquerysql
  636. *@parampageNo頁(yè)碼
  637. *@parampageSize每頁(yè)容量
  638. */
  639. public PagedStatementOracleImpl( String sql, int pageNo, int pageSize){
  640. super (sql,pageNo,pageSize);
  641. }
  642. /**
  643. *生成查詢一頁(yè)數(shù)據(jù)的sql語(yǔ)句
  644. *@paramsql原查詢語(yǔ)句
  645. *@startIndex開(kāi)始記錄位置
  646. *@size需要獲取的記錄數(shù)
  647. */
  648. protected String intiQuerySQL( String sql, int startIndex, int size){
  649. StringBuffer querySQL= new StringBuffer ();
  650. if (size!= super .MAX_PAGE_SIZE){
  651. querySQL.append("select*from(selectmy_table.*,rownumasmy_rownumfrom(")
  652. .append(sql)
  653. .append(")my_tablewhererownum<").append(startIndex+size)
  654. .append(")wheremy_rownum>=").append(startIndex);
  655. } else {
  656. querySQL.append("select*from(selectmy_table.*,rownumasmy_rownumfrom(")
  657. .append(sql)
  658. .append(")my_table")
  659. .append(")wheremy_rownum>=").append(startIndex);
  660. }
  661. return querySQL.toString();
  662. }
  663. /**
  664. *將ResultSet數(shù)據(jù)填充進(jìn)CachedRowSet
  665. */
  666. protected RowSet populate( ResultSet rs) throws SQLException {
  667. OracleCachedRowSetocrs= new OracleCachedRowSet();
  668. ocrs.populate(rs);
  669. return ocrs;
  670. }
  671. }

JSP分頁(yè)技術(shù)實(shí)現(xiàn)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦?。。?/p>

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 日本九九精品一区二区 | 无码日本精品久久久久久 | 成年人在线播放 | 亚洲人人 | 亚洲国产精品成人 | 国产精品日韩欧美在线第3页 | 欧美视频在线免费播放 | 91福利在线观看 | 起视碰碰97摸摸碰碰视频 | 米奇7777狠狠狠狠视频 | www.妞干网.com | 成人影院欧美大片免费看 | 奇米影视88 | 四虎精品 | 看全色黄大色黄大片色黄看的 | 欧美同性精品xxxx | 欧美国产伦久久久久 | 一本大道久久a久久综合 | 久草经典视频 | 国产精品v在线播放观看 | 精品一区二区三区在线观看视频 | 好骚综合97op | 高清午夜线观看免费 | 亚洲免费视频一区 | 色开心 | 狠狠骚| 91无限资源 | 精品亚洲一区二区三区 | 成人18视频在线 | 欧美国产免费 | 精品欧美一区二区久久久伦 | 色吊丝欧美 | 美女污污视频网站 | 久草视频在线免费播放 | 亚洲欧美日韩中文字幕在线不卡 | 国色天香综合网 | 99re在线观看 | 久久综合一 | 久久精品国产一区二区 | 91视频这里只有精品 | 99人中文字幕亚洲区 |