这次做的项目有要求实现翻页功能.
之前学javaee课的时候,老师曾给过翻页功能的例子,即将核心代码都写在jsp中.
[留言板翻页功能]
<body> <div id="main"> <% Connection conn=DBConnection.getConnection(); //创建可滚动的结果集。 Statement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY); ResultSet rs=stmt.executeQuery("select * from g_guestinfo order by g_time desc"); //移动游标至结果集的最后一行。 rs.last(); //得到当前行的行数,也就得到了数据库中留言的总数。 int rowCount=rs.getRow(); if(rowCount==0) { out.println("当前没有任何留言!"); return; } String strCurPage=request.getParameter("page"); //表示当前的页数。 int curPage; if(strCurPage==null) curPage=1; else curPage=Integer.parseInt(strCurPage); //定义每页显示的留言数。 int countPerPage=5; //计算显示所有留言需要的总页数。 int pageCount=(rowCount+countPerPage-1)/countPerPage; //移动游标至结果集中指定的行。如果显示的是第一页,curPage=1, //游标移动到第1行。 rs.absolute((curPage-1)*countPerPage+1); %> <% int i=0; int j=rowCount-(curPage-1)*countPerPage; //以循环的方式取出每页要显示的数据,因为在前面针对要显示的页数, //调用了rs.absolute((curPage-1)*countPerPage+1); //所以是从游标所在的位置取出当前页要显示的数据。 while(i<countPerPage && !rs.isAfterLast()) {%> <div class="g_info"> <div class="g_head"> <span class="spanleft">No.<%=j--%></span> <span class="spanleft"></span> <span class="g_name"><%=rs.getString("g_user")%></span> <span class="spanright"><a href="mailto:<%=rs.getString("g_mail") %>"><img src="img/mail.gif" border=0/></a></span> <span class="spanright"><a href=<%=rs.getString("g_home") %>><img src="img/home.gif" border=0/></a></span> </div> <div class="g_content"> <p><%=rs.getString("g_content")%></p> </div> <% Timestamp ts=rs.getTimestamp("g_time"); long lms=ts.getTime(); Date date=new Date(lms); Time time=new Time(lms); %> <div class="g_floor"> <span class="spanright"><a href=addel.jsp?g_id=<%=rs.getInt(1)%>>删除</a></span> <span class="spanright"><%out.println(date+" "+time);%></span> </div> </div> <% i++; rs.next(); } rs.close(); stmt.close(); conn.close(); %> <div class="g_page"> <% if(curPage==1) { %> <span>第一页 </span> <span>上一页</span> <% } else { %> <span><a href="admin.jsp?page=<%=1%>">第一页</a></span> <span><a href="admin.jsp?page=<%=curPage-1%>">上一页</a></span> <% } //如果当前页是最后一页,则显示不带链接的文字,如果不是最后一页, //则给用户提供跳转到最后一页和下一页的链接。 if(curPage==pageCount) { %> <span>下一页</span> <span>最后页 </span> <% } else { %> <span><a href="admin.jsp?page=<%=curPage+1%>">下一页</a></span> <span><a href="admin.jsp?page=<%=pageCount%>">最后页</a></span> <% } %> </div> </div> </body>
这样做的话,每次都要从数据库中取出所有数据,然后找到符合要求的那一页.而且这样做代码重用性不高.比如有三个模块,其中都要实现翻页功能,那么就要每一页都写这么多的代码.
去网上搜了一些解决方案,貌似都是把操作写在类里然后调用.方法应该是这样的,但我还是看的很迷糊.
后来进了一个人的新浪博客,汗,刚才找了半天没找着,大概的意思就是建立一个类并在其中定义一个函数.每次翻页时都访问这个类,返回相应页面的记录即可.(好像有点表述的不清楚了)...
举例子说明:
有三个模块:device,module,work,它们都各自有个**show.jsp的页面,其中用到翻页功能.以device为例我们可以这样做:
deviceshow.jsp
<table id="mytable" cellspacing="0"> <tr> <th>序号</th> <th>名称</th> <th>描述</th> </tr> <% String s=request.getParameter("page"); int gotoPage=1; if(s!=null) gotoPage=Integer.parseInt(request.getParameter("page")); ArrayList allUserList=PageBean.getInfo("Device",gotoPage); if(allUserList.size()!=0){ for(int i=0;i<allUserList.size();i++){ DevicetypeBean info=(DevicetypeBean)allUserList.get(i); %> <tr> <td><%=info.getNo() %></td> <td><%=info.getName() %></td> <%if(info.getComments()==null){%> <td> </td> <%}else {%> <td><%=info.getComments() %></td> <%} %> </tr> <% } } %> <tr> <td colspan="5"> <ul class="pagelist"> <% for(int i=1;i<=PageBean.PageCount;i++){ if(i==PageBean.curPage){%> <li class="pagecho"><%=i%></li> <%}else {%> <li><a href="PageQuery?page=<%=i%>&type=device&qname=<%=java.net.URLEncoder.encode(qname,"UTF-8")%>"><%=i%></a></li> <%} } if(PageBean.curPage!=PageBean.PageCount&&PageBean.PageCount!=0){ %> <li class="nextpage"><a href="PageQuery?page=<%=PageBean.curPage+1%>&type=device&qname=<%=java.net.URLEncoder.encode(qname,"UTF-8")%>">下一页</a></li> <%} %> </ul> </td> </tr> </table>
PageBean.java
package beans;
import java.util.ArrayList; import java.sql.*; import beans.DBConnection;
public class PageBean { public static int curPage; public static int PageCount; public static int countPerPage=10; public static ArrayList getInfo(String type,int gotoPage){ Connection conn=null; PreparedStatement ps=null; Statement st=null; ResultSet rs=null; ArrayList result=new ArrayList(); String sql=null; int startrow=(gotoPage-1)*countPerPage+1; int endrow=startrow+countPerPage-1; curPage=gotoPage; String table=null; String torder=null; if(type.equals("Device")){ table="(select * from ddpms_devicetype where name<>'原材料' and name<>'公司产品' and name<>'整机套件')"; torder="order by no"; } else if(type.equals("Module")){ table="ddpms_productmodule"; torder="order by no"; } else if(type.equals("Work")){ table="ddpms_workstage"; torder="order by code"; } try{ conn=DBConnection.getConnection(); if(qname==null||qname.equals("")||qname.equals("null")){ PageCount=getRow(table); //sql = "SELECT * FROM "+table+" WHERE rownum <? minus SELECT * FROM "+table+" WHERE rownum <?"; sql="select * from (select T.*,row_number() over ("+torder+") rn from "+table+" T) where rn between ? and ?"; ps = conn.prepareStatement(sql); ps.setInt(1, startrow); ps.setInt(2, endrow); } rs= ps.executeQuery(); while(rs.next()){ //依次取出每一条记录,组合成一个bean,放入ArrayList中 DevicetypeBean dt=new DevicetypeBean(); ModuleBean m=new ModuleBean(); WorkBean w=new WorkBean(); if(type.equals("Device")){ dt.setNo(rs.getInt("no")); dt.setName(rs.getString("name")); dt.setParentid(rs.getInt("parentid")); dt.setComments(rs.getString("comments")); result.add(dt); } else if(type.equals("Module")){ m.setNo(rs.getInt("no")); m.setName(rs.getString("name")); m.setComments(rs.getString("comments")); result.add(m); } else if(type.equals("Work")){ w.setNo(rs.getInt("no")); w.setName(rs.getString("name")); w.setCode(rs.getString("code")); w.setComments(rs.getString("comments")); result.add(w); } } }catch(Exception e){ e.printStackTrace(); } finally{ try{ rs.close(); ps.close(); conn.close(); }catch(Exception e){ e.printStackTrace(); } } return result; } public static int getRow(String table){ Connection conn=null; Statement st=null; ResultSet rs=null; int rowcount=0; try{ conn=DBConnection.getConnection(); String sql = "select * from "+table+""; st = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY); rs= st.executeQuery(sql); rs.last();/*要先将游标移到最后才能得到getRow,否则为0*/ rowcount=(rs.getRow()+countPerPage-1)/countPerPage; }catch(Exception e){ e.printStackTrace(); } finally{ try{ rs.close(); st.close(); conn.close(); }catch(Exception e){ e.printStackTrace(); } } return rowcount; } }
代码大概是这样,因为掺杂了其他功能,删了一些东西,可能看起来有些乱.
使用过程大概就是这样:
每次翻页时都会访问pagebean中的getInfo函数,并传递页数以及模块名称,pagebean中找到符合条件的记录装入list,再由jsp页面使用.
在做这部分的时候遇到了两个问题,弄了很长时间.
1.Oracle下用rownum进行分页时排序的错乱
---排序错乱(第1~5条) (SELECT * FROM (select * from ddpms_workstage order by ddpms_workstage.code) WHERE rownum <6) minus (SELECT * FROM (select * from ddpms_workstage order by ddpms_workstage.code) WHERE rownum <1)
--解决rownum错乱问题 select t2.* from (select t1.*, rownum rn from (select * from ddpms_workstage order by ddpms_workstage.code)t1 where rownum <= 5 )t2 where rn >0 --- select * from (select T.*,row_number() over (order by code) rn from ddpms_workstage T) where rn between 1 and 5;
2.URL传中文乱码
URL一般是不能传送中文的,非要传只能先转下编码,到后台再解码.
网友回答: 建议楼主看一下api使用这两个类来处理!
URLEncoder和URLDecoder
1.传递中文参数
JSP中使用URLEncoder类,如果要在url上附带中文参数,如“笔记本电脑”,应先对中文进行url编码!
<a href="/hello/servlet/add?id=0001&name= <%=URLEncoder.encode("笔记本电脑","UTF-8")%>&price=4000.00">*** </a>
2.接受参数参数
servlet中接受中文参数
String urlPar=request.getParameter("name");//(这里只是获得了url编码后的参数)
String Par=URLDecoder.decode(urlPar,"UTF-8");//(这里获得了反编码后的参数,就是笔记本电脑这个值)
总结
我想我已经说明白了,希望楼主理解,这里的编码为任意中文编码,但前后要一致,我一般JSP都用UTF-8进行编码!
网友回答: 晕~~~试了一下 上面接受时有些问题 该成这样就可以了!!!sorry!!!
2.接受参数参数
servlet中接受中文参数
String name=new String(request.getParameter("name").getBytes("ISO8859_1"),"UTF-8");
System.out.println(name);
----------------------------------------------------------------------------------------------------------------
这是在网上找到的解答,奇怪,用第二种方法不行,反倒是第一种可行.如下:
前台
<a href="PageQuery?
qname=<%=java.net.URLEncoder.encode(qname,"UTF-8")%>"><%=i%></a>
后台
String name=request.getParameter("qname");
String qname=java.net.URLDecoder.decode(name,"UTF-8");