| 
         
     
     | 
     | 
    
  
    | 
    一个Jsp初学者的学习过程(五) | 
   
  
     | 
   
  
     | 
   
  
    | 
     作者:未知  来源:月光软件站  加入时间:2005-5-13 月光软件站  | 
   
  
    一个Jsp初学者的学习过程(五)
  TheUnforgiven
 
  第五章  分页功能的实现
      在我逐步把我的留言板的功能完善的同时,我渐渐熟悉了对数据库的操作,这时我发现留言信息的目录越来越长了,我需要实现一个分页功能了,最初我尝试自己解决这个问题:     1、我应该把它的关键部分封装成一个bean,使它尽可能的能够重用;     2、通过资料了解有两种数据库查询方案:一、一次取得所有资料,然后在指定的页显示指定的资料;二、分次查询数据库,每次只获得本页的数据。考虑到数据库中记录数越多,方案一所占的服务器资源就越多(将所有的记录都放到内存中,假如有50万条记录的话……@$^*%@#),所以应该采用方案二;     3、首先要知道目标数据库里共有多少条记录(select count(*) from 表名),然后确定每页显示多少条记录,再根据它计算一共分多少页(最大页数)显示,这部分由bean1(在我的代码里就随便起个名叫PageBean)实现;获取当前要显示第几页的请求,查询本页要显示哪些条记录,将每条记录的内容作为一组数据返回给显示页面,这部分由bean2(CountBean)实现;显示页面(.jsp文件)显示各条记录的内容。     到这里我发现有两个难点:(1)查询从第m条到第n条记录的SQL语句不会写,通过在网上查找资料,这个问题得到解决;(2)bean2返回给显示页面的值是个二维的数组,这个数组怎么传呢?于是不得不上网翻书查找资料,最终发现由Vector(向量)来解决,由于没有工具书,无法针对Vector进一步学习,就只好分析代码,好在最后分析明白了——到目前为止,也只是明白了那段代码,仍然无法做到能够应用。     下面是这三个文件的代码: -----------------------------------------PageBean.java----------------------------------------------- //该bean用于实现分页功能时得到总的记录数和最大的页数 package ringz.javabeans; import java.io.*;  import java.sql.*; public class PageBean {    private int maxRowCount;//最大记录数    private int onePageRowCount;//每页显示的记录数    private int maxPageCount;//最大页数    private String classforname;    private String servanddb;    private String sql;    //    //得到关于目标数据库的搜索条件    public void setSql(String s1,String s2,String sql)    {      this.classforname=s1;      this.servanddb=s2;      this.sql=sql;    }        //得到onePageRowCount    public void setOnePageRowCount(int counts)     {       onePageRowCount=counts;     }
     //计算maxRowCount并返回    public int getMaxRowCount()throws Exception     {      try      {      Class.forName(classforname);//载入驱动程式类别      Connection con=DriverManager.getConnection(servanddb);//建立数据库连接      Statement stmt=con.createStatement();//建立Statement变量          ResultSet rs=stmt.executeQuery(sql);      if (rs.next())        maxRowCount=rs.getInt(1);      rs.close();      stmt.close();      con.close();      return maxRowCount;      }//try      catch (Exception e)      {        e.printStackTrace();       throw e;       }     }//getMaxRowCount()   
     //根据maxRowCount和onePageRowCount计算出maxPageCount并返回    public int getMaxPageCount()     {       if (maxRowCount%onePageRowCount==0)         maxPageCount=maxRowCount/onePageRowCount;       else         maxPageCount=maxRowCount/onePageRowCount+1;       return maxPageCount;     }  } --------------------------------------------------------------------------------- ----------------------------CountBean.java------------------------------------ //该bean用于接收具体页数然后返回该页应显示的记录 package ringz.javabeans; import java.util.*; import java.io.*;  import java.sql.*; public class CountBean {    private int pageNum;//当前是第几页    private String classforname;    private String servanddb;    private String sql;    Vector v=new Vector();        //得到关于目标数据库的搜索条件    public void setSql(String s1,String s2,String sqlstr)    {         this.classforname=s1;      this.servanddb=s2;      this.sql=sqlstr;     }        //得到pageNum    public void setPageNum(int pagenum)     {       this.pageNum=pagenum;      }           //返回结果    public Vector getResult(String listname[])throws Exception     {      int num=listname.length;//得到数组的长度      String listName[]=new String[num];//定义一个大小为num的string型数组      for(int i=0;i<num;i++)        listName[i]=listname[i];//将目标数组的内容传给listName数组            try      {      Class.forName(classforname);      Connection con=DriverManager.getConnection(servanddb);      Statement stmt=con.createStatement();         ResultSet rs=stmt.executeQuery(sql);      int i=1;      while(rs.next())       {         Object[] obj=new Object[num];         for(int j=0;j<num;j++)           obj[j]=rs.getString(listName[j]);         v.add(obj);         i++;        }//while      rs.close();      stmt.close();      con.close();      return v;      }//try      catch(Exception e)      {       e.printStackTrace();       throw e;       }//catch     } } ----------------------------------------------------------------------------------     编译上面这两个文件的时候,发现如果不把“错误”扔掉(throw e),就无法编译成功,我不明白具体原因。 -----------------------------------page.jsp--------------------------------------- <%@ include file="include.inc"%> <%@ page contentType="text/html;charset=gb2312"%> <jsp:useBean id="page1" scope="page" class="ringz.javabeans.PageBean"/> <jsp:useBean id="page2" scope="page" class="ringz.javabeans.CountBean"/> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> <title>分页的实现</title> <style type="text/css"> <!-- body {     margin-left: 10%;     margin-right: 10%;      } --> </style> <script language="JavaScript" type="text/JavaScript"> <!-- function jumping(jump){ //v3.0   ***用于页面跳转   var pageID=jump.value;   var url=pageID;   window.location.href = url; } //--> </script> </head>
  <body> <% int pageNum; try {   pageNum=Integer.parseInt(request.getParameter("page"));//得到“要显示第几页” } catch(Exception e) {   pageNum=1;//如果出错说明pageNum没有接收到"page",那么就把pageNum初始为1 } int onePageRowCount=10;//每页的条数************按需要改变 String s1="oracle.jdbc.driver.OracleDriver";//定义载入驱动程式的字符串 String s2="jdbc:oracle:thin:name/password@ringz:1521:rock";//定义建立数据库连接的字符串************按需要改变 String sql="select count(*) from article";//确定记录总数的查询语句************按需要改变 page1.setSql(s1,s2,sql); page1.setOnePageRowCount(onePageRowCount); int maxRowCount=page1.getMaxRowCount();//获得记录总数 int maxPageCount=page1.getMaxPageCount();//获得总的页数 page2.setPageNum(pageNum); String listname[]={"ID","author","time","title"};//要查询的字段名************按需要改变 int max=pageNum*onePageRowCount;//本页最后一条记录的行号 int min=(pageNum-1)*onePageRowCount+1;//本页第一条记录的行号 String sqlstr="select b.* from (select a.*,rownum row_num from (select * from article order by time desc) a where rownum<='"+max+"') b where row_num>='"+min+"'";//************按需要改变 page2.setSql(s1,s2,sqlstr); if(maxRowCount>0)   out.println("<div align='left'>共有"+maxRowCount+"条记录,每页显示"+onePageRowCount+"条。</div>"); %> <table width="100%" border="1" align="center" cellpadding="0" cellspacing="0" bordercolorlight="#000000"> <tr bgcolor="#00CCFF"> <td align="center">标题</td> <td align="center">作者</td> <td align="center">日期</td> </tr> <% java.util.Vector v=page2.getResult(listname); java.util.Enumeration e=v.elements(); while(e.hasMoreElements()) {  Object[] obj=(Object[])e.nextElement();//****************注意修改下面的几行  String id=obj[0].toString();  String name=obj[1].toString();  String time=obj[2].toString();  String title=obj[3].toString();  out.println("<tr>");  out.println("<td bgcolor='#eeeeee'><div align='left'><font color='#eeeeee'><a href=view.jsp?ID="+id+">"+title+"</a></font></div></td>");  out.println("<td width='15%' bgcolor='#ffff99'><div align='center'>"+name+"</div></td>");  out.println("<td width='30%' bgcolor='#9999ff'><div align='center'>"+time+"</div></td>");  out.println("</tr>"); } %> </table> <div align="right"> <% String fileName="page";//**************************将文件名作为变量*********************** out.print("第<font color=red>"+pageNum+"</font>页     共"+maxPageCount+"页   "); if (maxPageCount>1)//不只有一页 {   if (pageNum==1)//当前页是首页    {     out.print("首页 | 上一页 | <a href="+fileName+".jsp?page="+(pageNum+1)+">下一页</a> | ");     out.print("<a href="+fileName+".jsp?page="+maxPageCount+">尾页</a> ");     }//if (pageNum==1)   else    {      if (pageNum==maxPageCount)//当前页是尾页       {        out.print("<a href="+fileName+".jsp?page=1>首页</a> | ");        out.print("<a href="+fileName+".jsp?page="+(pageNum-1)+">上一页</a> | 下一页 | 尾页 ");        }//if (pageNum==maxPageCount)      else//当前页不是上面的2种情况       {        out.print("<a href="+fileName+".jsp?page=1>首页</a> | ");        out.print("<a href="+fileName+".jsp?page="+(pageNum-1)+">上一页</a> | ");        out.print("<a href="+fileName+".jsp?page="+(pageNum+1)+">下一页</a> | ");        out.print("<a href="+fileName+".jsp?page="+maxPageCount+">尾页</a> ");         }    } %> 跳转到第   <select name="jumps" onChange="jumping(this)">   <%    for (int i=1;i<=maxPageCount;i++)    {      if (i==pageNum)       {%>     <option value="<%=fileName%>.jsp?page=<%=i%>" selected><%=i%></option>     <%} else {%>     <option value="<%=fileName%>.jsp?page=<%=i%>"><%=i%></option>     <%} } %>   </select> 页 <% }//if (maxPageCount!=1) %> </div> </body> </html> ----------------------------------------------------------------------------------
      整个的分页功能写完后,我发现还是有很大的不足:显示分页的页面(page.jsp)代码太多,其他页面引用该功能的时候还是要从这里复制大段的代码,而且其中需要根据实际情况改动的地方多达七处(标注很多*的地方),这很容易出错,不利于管理使用,但是至今我仍找不到一个合适的方法解决这个问题——希望高手们扔玉。
 
 
  
 
  | 
   
  
     | 
   
  
     相关文章:相关软件:  | 
   
   
      |