这次做的项目有要求实现翻页功能.
之前学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");