JSP分页技术实现

目前比较广泛使用的分页方式是将查询结果缓存在HttpSession或有状态bean中,翻页的时候从缓存中取出一页数据显示。这种方法有两个主要的缺点:一是用户可能看到的是过期数据;二是如果数据量非常大时第一次查询遍历结果集会耗费很长时间,并且缓存的数据也会占用大量内存,效率明显下降。
  其它常见的方法还有每次翻页都查询一次数据库,从ResultSet中只取出一页数据(使用rs.last();rs.getRow()获得总计录条数,使用rs.absolute()定位到本页起始记录)。这种方式在某些数据库(如oracle)的JDBC实现中差不多也是需要遍历所有记录,实验证明在记录数很大时速度非常慢。
  至于缓存结果集ResultSet的方法则完全是一种错误的做法。因为ResultSet在Statement或Connection关闭时也会被关闭,如果要使ResultSet有效势必长时间占用数据库连接。

  因此比较好的分页做法应该是每次翻页的时候只从数据库里检索页面大小的块区的数据。这样虽然每次翻页都需要查询数据库,但查询出的记录数很少,网络传输数据量不大,如果使用连接池更可以略过最耗时的建立数据库连接过程。而在数据库端有各种成熟的优化技术用于提高查询速度,比在应用服务器层做缓存有效多了。

  在oracle数据库中查询结果的行号使用伪列ROWNUM表示(从1开始)。例如select*fromemployeewhererownum<10返回前10条记录。但因为rownum是在查询之后排序之前赋值的,所以查询employee按birthday排序的第100到120条记录应该这么写:

select*from(
selectmy_table.*,rownumasmy_rownumfrom(
selectname,birthdayfromemployeeorderbybirthday
)my_tablewhererownum<120
)wheremy_rownum>=100


  mySQL可以使用LIMIT子句:
    selectname,birthdayfromemployeeorderbybirthdayLIMIT99,20
  DB2有rownumber()函数用于获取当前行数。
  SQLServer没研究过,可以参考这篇文章:
http://www.csdn.net/develop/article/18/18627.shtm

  在Web程序中分页会被频繁使用,但分页的实现细节却是编程过程中比较麻烦的事情。大多分页显示的查询操作都同时需要处理复杂的多重查询条件,sql语句需要动态拼接组成,再加上分页需要的记录定位、总记录条数查询以及查询结果的遍历、封装和显示,程序会变得很复杂并且难以理解。因此需要一些工具类简化分页代码,使程序员专注于业务逻辑部分。下面是我设计的两个工具类:
  PagedStatement封装了数据库连接、总记录数查询、分页查询、结果数据封装和关闭数据库连接等操作,并使用了PreparedStatement支持动态设置参数。
  RowSetPage参考PetStore的pagebypageiterator模式,设计RowSetPage用于封装查询结果(使用OracleCachedRowSet缓存查询出的一页数据,关于使用CachedRowSet封装数据库查询结果请参考
JSP页面查询显示常用模式)以及当前页码、总记录条数、当前记录数等信息,并且可以生成简单的HTML分页代码。
  PagedStatement查询的结果封装成RowsetPage。

  下面是简单的使用示例

  1. //DAO查询数据部分代码:
  2. publicRowSetPagegetEmployee(Stringgender,intpageNo)throwsException{
  3. Stringsql="selectemp_id,emp_code,user_name,real_namefromemployeewheregender=?";
  4. //使用Oracle数据库的分页查询实现,每页显示5条
  5. PagedStatementpst=newPagedStatementOracleImpl(sql,pageNo,5);
  6. pst.setString(1,gender);
  7. returnpst.executeQuery();
  8. }
  9. //Servlet处理查询请求部分代码:
  10. intpageNo;
  11. try{
  12. //可以通过参数pageno获得用户选择的页码
  13. pageNo=Integer.parseInt(request.getParameter("pageno"));
  14. }catch(Exceptionex){
  15. //默认为第一页
  16. pageNo=1;
  17. }
  18. Stringgender=request.getParameter("gender");
  19. request.setAttribute("empPage",myBean.getEmployee(gender,pageNo));
  20. //JSP显示部分代码
  21. <%@pageimport="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.RowSetempRS=(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. //显示总页数和当前页数(pageno)以及分页代码。
  55. //此处doQuery为页面上提交查询动作的javascript函数名,pageno为标识当前页码的参数名
  56. %>
  57. <tdcolspan=4><%=empPage.getHTML("doQuery","pageno")%></td>
  58. </tr>
  59. </table>
  60. </form>


  效果如图:


  因为分页显示一般都会伴有查询条件和查询动作,页面应已经有校验查询条件和提交查询的javascript方法(如上面的doQuery),所以RowSetPage.getHTML()生成的分页代码在用户选择新页码时直接回调前面的处理提交查询的javascript方法。注意在显示查询结果的时候上次的查询条件也需要保持,如<inputtype=textname=gendersize=1value="<%=request.getParameter("gender")%>">。同时由于页码的参数名可以指定,因此也支持在同一页面中有多个分页区。
  另一种分页代码实现是生成每一页的URL,将查询参数和页码作为QueryString附在URL后面。这种方法的缺陷是在查询条件比较复杂时难以处理,并且需要指定处理查询动作的servlet,可能不适合某些定制的查询操作。
  如果对RowSetPage.getHTML()生成的默认分页代码不满意可以编写自己的分页处理代码,RowSetPage提供了很多getter方法用于获取相关信息(如当前页码、总页数、总记录数和当前记录数等)。
  在实际应用中可以将分页查询和显示做成jsptaglib,进一步简化JSP代码,屏蔽JavaCode。

附:分页工具类的源代码,有注释,应该很容易理解。

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



您可以任意使用这些源代码,但必须保留[email protected]字样

  1. ///////////////////////////////////
  2. //
  3. //Page.java
  4. //author:[email protected]
  5. //
  6. ///////////////////////////////////
  7. packagepage;
  8. importjava.util.List;
  9. importjava.util.ArrayList;
  10. importjava.util.Collection;
  11. importjava.util.Collections;
  12. /**
  13. *Title:分页对象<br>
  14. *Description:用于包含数据及分页信息的对象<br>
  15. *Page类实现了用于显示分页信息的基本方法,但未指定所含数据的类型,
  16. *可根据需要实现以特定方式组织数据的子类,<br>
  17. *如RowSetPage以RowSet封装数据,ListPage以List封装数据<br>
  18. *Copyright:Copyright(c)2002<br>
  19. *@[email protected]<br>
  20. *@version1.0
  21. */
  22. publicclassPageimplementsjava.io.Serializable{
  23. publicstaticfinalPageEMPTY_PAGE=newPage();
  24. publicstaticfinalintDEFAULT_PAGE_SIZE=20;
  25. publicstaticfinalintMAX_PAGE_SIZE=9999;
  26. privateintmyPageSize=DEFAULT_PAGE_SIZE;
  27. privateintstart;
  28. privateintavaCount,totalSize;
  29. privateObjectdata;
  30. privateintcurrentPageno;
  31. privateinttotalPageCount;
  32. /**
  33. *默认构造方法,只构造空页
  34. */
  35. protectedPage(){
  36. this.init(0,0,0,DEFAULT_PAGE_SIZE,newObject());
  37. }
  38. /**
  39. *分页数据初始方法,由子类调用
  40. *@paramstart本页数据在数据库中的起始位置
  41. *@paramavaCount本页包含的数据条数
  42. *@paramtotalSize数据库中总记录条数
  43. *@parampageSize本页容量
  44. *@paramdata本页包含的数据
  45. */
  46. protectedvoidinit(intstart,intavaCount,inttotalSize,intpageSize,Objectdata){
  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("记录条数大于总条数?!");
  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. publicObjectgetData(){
  66. returnthis.data;
  67. }
  68. /**
  69. *取本页数据容量(本页能包含的记录数)
  70. *@return本页能包含的记录数
  71. */
  72. publicintgetPageSize(){
  73. returnthis.myPageSize;
  74. }
  75. /**
  76. *是否有下一页
  77. *@return是否有下一页
  78. */
  79. publicbooleanhasNextPage(){
  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. *是否有上一页
  90. *@return是否有上一页
  91. */
  92. publicbooleanhasPreviousPage(){
  93. /*
  94. returnstart>1;
  95. */
  96. return(this.getCurrentPageNo()>1);
  97. }
  98. /**
  99. *获取当前页第一条数据在数据库中的位置
  100. *@return
  101. */
  102. publicintgetStart(){
  103. returnstart;
  104. }
  105. /**
  106. *获取当前页最后一条数据在数据库中的位置
  107. *@return
  108. */
  109. publicintgetEnd(){
  110. intend=this.getStart()+this.getSize()-1;
  111. if(end<0){
  112. end=0;
  113. }
  114. returnend;
  115. }
  116. /**
  117. *获取上一页第一条数据在数据库中的位置
  118. *@return记录对应的rownum
  119. */
  120. publicintgetStartOfPreviousPage(){
  121. returnMath.max(start-myPageSize,1);
  122. }
  123. /**
  124. *获取下一页第一条数据在数据库中的位置
  125. *@return记录对应的rownum
  126. */
  127. publicintgetStartOfNextPage(){
  128. returnstart+avaCount;
  129. }
  130. /**
  131. *获取任一页第一条数据在数据库中的位置,每页条数使用默认值
  132. *@parampageNo页号
  133. *@return记录对应的rownum
  134. */
  135. publicstaticintgetStartOfAnyPage(intpageNo){
  136. returngetStartOfAnyPage(pageNo,DEFAULT_PAGE_SIZE);
  137. }
  138. /**
  139. *获取任一页第一条数据在数据库中的位置
  140. *@parampageNo页号
  141. *@parampageSize每页包含的记录数
  142. *@return记录对应的rownum
  143. */
  144. publicstaticintgetStartOfAnyPage(intpageNo,intpageSize){
  145. intstartIndex=(pageNo-1)*pageSize+1;
  146. if(startIndex<1)startIndex=1;
  147. //System.out.println("PageNotoStartIndex:"+pageNo+"-"+startIndex);
  148. returnstartIndex;
  149. }
  150. /**
  151. *取本页包含的记录数
  152. *@return本页包含的记录数
  153. */
  154. publicintgetSize(){
  155. returnavaCount;
  156. }
  157. /**
  158. *取数据库中包含的总记录数
  159. *@return数据库中包含的总记录数
  160. */
  161. publicintgetTotalSize(){
  162. returnthis.totalSize;
  163. }
  164. /**
  165. *取当前页码
  166. *@return当前页码
  167. */
  168. publicintgetCurrentPageNo(){
  169. returnthis.currentPageno;
  170. }
  171. /**
  172. *取总页码
  173. *@return总页码
  174. */
  175. publicintgetTotalPageCount(){
  176. returnthis.totalPageCount;
  177. }
  178. /**
  179. *
  180. *@paramqueryJSFunctionName实现分页的JS脚本名字,页码变动时会自动回调该方法
  181. *@parampageNoParamName页码参数名称
  182. *@return
  183. */
  184. publicStringgetHTML(StringqueryJSFunctionName,StringpageNoParamName){
  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. StringgotoPage="_"+queryJSFunctionName;
  195. StringBufferhtml=newStringBuffer("/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("页")
  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(")'>上一页</a>]/n");
  231. }
  232. html.append("第")
  233. .append("<selectname='")
  234. .append(pageNoParamName).append("'onChange='javascript:")
  235. .append(gotoPage).append("(this.value)'>/n");
  236. Stringselected="selected";
  237. for(inti=1;i<=getTotalPageCount();i++){
  238. if(i==getCurrentPageNo())
  239. selected="selected";
  240. elseselected="";
  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>页/n");
  250. if(hasNextPage()){
  251. html.append("[<ahref='javascript:").append(gotoPage)
  252. .append("(").append((getCurrentPageNo()+1))
  253. .append(")'>下一页</a>]/n");
  254. }
  255. html.append("</td></tr></table>/n");
  256. returnhtml.toString();
  257. }
  258. }
  259. ///////////////////////////////////
  260. //
  261. //RowSetPage.java
  262. //author:[email protected]
  263. //
  264. ///////////////////////////////////
  265. packagepage;
  266. importjavax.sql.RowSet;
  267. /**
  268. *<p>Title:RowSetPage</p>
  269. *<p>Description:使用RowSet封装数据的分页对象</p>
  270. *<p>Copyright:Copyright(c)2003</p>
  271. *@[email protected]
  272. *@version1.0
  273. */
  274. publicclassRowSetPageextendsPage{
  275. privatejavax.sql.RowSetrs;
  276. /**
  277. *空页
  278. */
  279. publicstaticfinalRowSetPageEMPTY_PAGE=newRowSetPage();
  280. /**
  281. *默认构造方法,创建空页
  282. */
  283. publicRowSetPage(){
  284. this(null,0,0);
  285. }
  286. /**
  287. *构造分页对象
  288. *@paramcrs包含一页数据的OracleCachedRowSet
  289. *@paramstart该页数据在数据库中的起始位置
  290. *@paramtotalSize数据库中包含的记录总数
  291. */
  292. publicRowSetPage(RowSetcrs,intstart,inttotalSize){
  293. this(crs,start,totalSize,Page.DEFAULT_PAGE_SIZE);
  294. }
  295. /**
  296. *构造分页对象
  297. *@paramcrs包含一页数据的OracleCachedRowSet
  298. *@paramstart该页数据在数据库中的起始位置
  299. *@paramtotalSize数据库中包含的记录总数
  300. *@pageSize本页能容纳的记录数
  301. */
  302. publicRowSetPage(RowSetcrs,intstart,inttotalSize,intpageSize){
  303. try{
  304. intavaCount=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.SQLExceptionsqle){
  316. thrownewRuntimeException(sqle.toString());
  317. }
  318. }
  319. /**
  320. *取分页对象中的记录数据
  321. */
  322. publicjavax.sql.RowSetgetRowSet(){
  323. returnrs;
  324. }
  325. }
  326. ///////////////////////////////////
  327. //
  328. //PagedStatement.java
  329. //author:[email protected]
  330. //
  331. ///////////////////////////////////
  332. packagepage;
  333. importfoo.DBUtil;
  334. importjava.math.BigDecimal;
  335. importjava.util.List;
  336. importjava.util.Iterator;
  337. importjava.util.Collections;
  338. importjava.sql.Connection;
  339. importjava.sql.SQLException;
  340. importjava.sql.ResultSet;
  341. importjava.sql.Statement;
  342. importjava.sql.PreparedStatement;
  343. importjava.sql.Timestamp;
  344. importjavax.sql.RowSet;
  345. /**
  346. *<p>Title:分页查询</p>
  347. *<p>Description:根据查询语句和页码查询出当页数据</p>
  348. *<p>Copyright:Copyright(c)2002</p>
  349. *@[email protected]
  350. *@version1.0
  351. */
  352. publicabstractclassPagedStatement{
  353. publicfinalstaticintMAX_PAGE_SIZE=Page.MAX_PAGE_SIZE;
  354. protectedStringcountSQL,querySQL;
  355. protectedintpageNo,pageSize,startIndex,totalCount;
  356. protectedjavax.sql.RowSetrowSet;
  357. protectedRowSetPagerowSetPage;
  358. privateListboundParams;
  359. /**
  360. *构造一查询出所有数据的PageStatement
  361. *@paramsqlquerysql
  362. */
  363. publicPagedStatement(Stringsql){
  364. this(sql,1,MAX_PAGE_SIZE);
  365. }
  366. /**
  367. *构造一查询出当页数据的PageStatement
  368. *@paramsqlquerysql
  369. *@parampageNo页码
  370. */
  371. publicPagedStatement(Stringsql,intpageNo){
  372. this(sql,pageNo,Page.DEFAULT_PAGE_SIZE);
  373. }
  374. /**
  375. *构造一查询出当页数据的PageStatement,并指定每页显示记录条数
  376. *@paramsqlquerysql
  377. *@parampageNo页码
  378. *@parampageSize每页容量
  379. */
  380. publicPagedStatement(Stringsql,intpageNo,intpageSize){
  381. this.pageNo=pageNo;
  382. this.pageSize=pageSize;
  383. this.startIndex=Page.getStartOfAnyPage(pageNo,pageSize);
  384. this.boundParams=Collections.synchronizedList(newjava.util.LinkedList());
  385. this.countSQL="selectcount(*)from("+sql+")";
  386. this.querySQL=intiQuerySQL(sql,this.startIndex,pageSize);
  387. }
  388. /**
  389. *生成查询一页数据的sql语句
  390. *@paramsql原查询语句
  391. *@startIndex开始记录位置
  392. *@size需要获取的记录数
  393. */
  394. protectedabstractStringintiQuerySQL(Stringsql,intstartIndex,intsize);
  395. /**
  396. *使用给出的对象设置指定参数的值
  397. *@paramindex第一个参数为1,第二个为2,。。。
  398. *@paramobj包含参数值的对象
  399. */
  400. publicvoidsetObject(intindex,Objectobj)throwsSQLException{
  401. BoundParambp=newBoundParam(index,obj);
  402. boundParams.remove(bp);
  403. boundParams.add(bp);
  404. }
  405. /**
  406. *使用给出的对象设置指定参数的值
  407. *@paramindex第一个参数为1,第二个为2,。。。
  408. *@paramobj包含参数值的对象
  409. *@paramtargetSqlType参数的数据库类型
  410. */
  411. publicvoidsetObject(intindex,Objectobj,inttargetSqlType)throwsSQLException{
  412. BoundParambp=newBoundParam(index,obj,targetSqlType);
  413. boundParams.remove(bp);
  414. boundParams.add(bp);
  415. }
  416. /**
  417. *使用给出的对象设置指定参数的值
  418. *@paramindex第一个参数为1,第二个为2,。。。
  419. *@paramobj包含参数值的对象
  420. *@paramtargetSqlType参数的数据库类型(常量定义在java.sql.Types中)
  421. *@paramscale精度,小数点后的位数
  422. *(只对targetSqlType是Types.NUMBER或Types.DECIMAL有效,其它类型则忽略)
  423. */
  424. publicvoidsetObject(intindex,Objectobj,inttargetSqlType,intscale)throwsSQLException{
  425. BoundParambp=newBoundParam(index,obj,targetSqlType,scale);
  426. boundParams.remove(bp);
  427. boundParams.add(bp);
  428. }
  429. /**
  430. *使用给出的字符串设置指定参数的值
  431. *@paramindex第一个参数为1,第二个为2,。。。
  432. *@paramstr包含参数值的字符串
  433. */
  434. publicvoidsetString(intindex,Stringstr)throwsSQLException{
  435. BoundParambp=newBoundParam(index,str);
  436. boundParams.remove(bp);
  437. boundParams.add(bp);
  438. }
  439. /**
  440. *使用给出的字符串设置指定参数的值
  441. *@paramindex第一个参数为1,第二个为2,。。。
  442. *@paramtimestamp包含参数值的时间戳
  443. */
  444. publicvoidsetTimestamp(intindex,Timestamptimestamp)throwsSQLException{
  445. BoundParambp=newBoundParam(index,timestamp);
  446. boundParams.remove(bp);
  447. boundParams.add(bp);
  448. }
  449. /**
  450. *使用给出的整数设置指定参数的值
  451. *@paramindex第一个参数为1,第二个为2,。。。
  452. *@paramvalue包含参数值的整数
  453. */
  454. publicvoidsetInt(intindex,intvalue)throwsSQLException{
  455. BoundParambp=newBoundParam(index,newInteger(value));
  456. boundParams.remove(bp);
  457. boundParams.add(bp);
  458. }
  459. /**
  460. *使用给出的长整数设置指定参数的值
  461. *@paramindex第一个参数为1,第二个为2,。。。
  462. *@paramvalue包含参数值的长整数
  463. */
  464. publicvoidsetLong(intindex,longvalue)throwsSQLException{
  465. BoundParambp=newBoundParam(index,newLong(value));
  466. boundParams.remove(bp);
  467. boundParams.add(bp);
  468. }
  469. /**
  470. *使用给出的双精度浮点数设置指定参数的值
  471. *@paramindex第一个参数为1,第二个为2,。。。
  472. *@paramvalue包含参数值的双精度浮点数
  473. */
  474. publicvoidsetDouble(intindex,doublevalue)throwsSQLException{
  475. BoundParambp=newBoundParam(index,newDouble(value));
  476. boundParams.remove(bp);
  477. boundParams.add(bp);
  478. }
  479. /**
  480. *使用给出的BigDecimal设置指定参数的值
  481. *@paramindex第一个参数为1,第二个为2,。。。
  482. *@parambd包含参数值的BigDecimal
  483. */
  484. publicvoidsetBigDecimal(intindex,BigDecimalbd)throwsSQLException{
  485. BoundParambp=newBoundParam(index,bd);
  486. boundParams.remove(bp);
  487. boundParams.add(bp);
  488. }
  489. privatevoidsetParams(PreparedStatementpst)throwsSQLException{
  490. if(pst==null||this.boundParams==null||this.boundParams.size()==0)return;
  491. BoundParamparam;
  492. for(Iteratoritr=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. *执行查询取得一页数据,执行结束后关闭数据库连接
  504. *@returnRowSetPage
  505. *@throwsSQLException
  506. */
  507. publicRowSetPageexecuteQuery()throwsSQLException{
  508. System.out.println("executeQueryUsingPreparedStatement");
  509. Connectionconn=DBUtil.getConnection();
  510. PreparedStatementpst=null;
  511. ResultSetrs=null;

你可能感兴趣的:(JavaScript,sql,jsp,数据库,null,sqlserver)