分页查询功能一直是web编程中常用的技术,如何实现可重复使用而又简单的分页技术呢,下面的代码可以提供一些参考,实现用户列表的分页显示,当其它数据需分页显示时,可以复用其中的分页对象 (SplitPage.java),然后提供实现dao接口的类. 先列出这个例子中的接口类和页面文件清单:
1.数据库连接对象:DBConnection,获取数据连接对象getConnection();
2.分页(类)对象:SplitPage.java,提供页面参数(是否首页/尾页/ 当前第n页等)
3.数据库访问接口:dao,提供业务逻辑中对数据库操作接口, 用于分页查寻的接口方法是:
findAll(SplitPage sp)//方法的输入参数为分页对象
getRows()//提供总的记录数
UserDao.java用于实现这个接口.
4.用户JavaBean:User.java,分页显示用户列表时的用户对象.
5.userList.jsp:分页显示用户列表jsp页面.
============================================================
下面是详细介绍:
------------------------------------------------------------
1.关于数据库连接对象,实现下面的方法,为dao提供Connection对象
//获得数据库连接
public class DBUtil {
protected static Connection cnt = null;
protected static Statement stmt;
protected static ResultSet rs;
protected static String dbClassName = "com.mysql.jdbc.Driver";
/*
* 连接数据库
*/
protected DBUtil() {
if (cnt == null) {
try {
Class.forName(dbClassName);
cnt = DriverManager
.getConnection("jdbc:mysql://localhost/youdbname?"
+ "user=root&password=key");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException s) {
System.out.print("出错");
s.printStackTrace();
}
} else
return;
}
/*
* 查询语句
*/
public static ResultSet executeQuery(String sql) {
try {
if (cnt == null)
new DBUtil();
return (cnt.createStatement().executeQuery(sql));
} catch (SQLException e) {
e.printStackTrace();
return null;
} finally {
}
}
/*
* 更新(添加)语句
*/
public static int executeUpdate(String sql) {
try {
if (cnt == null)
new DBUtil();
return cnt.createStatement().executeUpdate(sql);
} catch (SQLException e) {
e.printStackTrace();
return -1;
} finally {
}
}
/*
* 断开数据库连接,关闭文件
*/
public static void CloseAll() {
try {
if (rs != null) {
rs.close();
rs = null;
}
if (stmt != null) {
stmt.close();
stmt = null;
}
if (cnt != null) {
cnt.close();
cnt = null;
}
} catch (SQLException ac) {
ac.printStackTrace();
}
}
}
------------------------------------------------------------
2.分页对象的实现:
public class SplitPage {
//分页请求时,请求标识参数
final public static String FIRSTPAGE="first";//请求第一页
final public static String PREVIOUSEPAGE="previous";//请求上一页
final public static String NEXTPAGE="next";//请求下一页
final public static String LASTPAGE="last";//请求最后一页
private int pageRows=3;//每页显示记录数,默认3条,可以在页面设置
private int totalRows=0;//总的记录数,这个参数由数据库dao对象提供
private int currentPage=1;//当前显示的页面编号,默认第一页
private int firstPage=1;//首页位置,默认第一页
private int totalPages=1;//总的页面数量,默认就一页
public int getCurrentPage() {
return currentPage;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
public int getFirstPage() {
return firstPage;
}
public void setFirstPage(int firstPage) {
this.firstPage = firstPage;
}
public int getPageRows() {
return pageRows;
}
public void setPageRows(int pageRows) {
if(pageRows==0)throw new ArithmeticException();
this.pageRows = pageRows;//如果pageRows被设置为零,应当抛出异常.
//修改每页显示记录数,将会直接影响总页面数,所以要同时修改
this.totalPages=(this.totalRows%this.pageRows==0)?this.totalRows/this.pageRows:this.totalRows/this.pageRows+1;
}
public int getTotalRows() {
return totalRows;
}
//设置分页对象的总记录属性后,就应该根据每页面显示记录数,计算得到总的页面数
public void setTotalRows(int totalRows) {
this.totalRows = totalRows;
//计算总的页面数(或最后的页面号),两个整数相除如果刚好除尽,值就是相除后的商,否则如果有余数,商应当还加1.
this.totalPages=(this.totalRows%this.pageRows==0)?this.totalRows/this.pageRows:this.totalRows/this.pageRows+1;
}
//不应该提供方法设置总页面数,它是计算得到的
//但应当提供获取总页面数的方法.
public int getTotalPages() {
return totalPages;
}
//根据请求页面的标识参数,重新计算当前要显示的页面
//核心方法,实现分页显示功能.
public int confirmPage(String flag){
int newPage=this.currentPage;
if(flag!=null){//flag只可能是下面值之一
if(flag.equals(SplitPage.FIRSTPAGE)){
newPage=1;
}else if(flag.equals(SplitPage.LASTPAGE)){
newPage=this.totalPages;
}else if(flag.equals(SplitPage.NEXTPAGE)){
//页面总数和当前页面编号相等吗,如果是那么页面编号不往后走,否则页面编号加一
newPage=(this.totalPages==this.currentPage)?this.currentPage:this.currentPage+1;
}else if(flag.equals(SplitPage.PREVIOUSEPAGE)){
//第一个页面和当前页面相等吗,如果是那么页面编号不往前走,否则页面编号减一
newPage=(this.firstPage==this.currentPage)?this.currentPage:this.currentPage-1;
}else{//否则是一个数字字符串
int tpage=Integer.parseInt(flag.trim());
newPage=tpage;
}
}else{//如果请求标识参数为空,那么当前页码不变
newPage=this.currentPage;
}
//在返回前设置当前页面
this.setCurrentPage(newPage);
return newPage;
}
}
------------------------------------------------------------
3.在UserDao.java中实现接口方法findAll(SplitPage sp)
提供数据集合的分页列表.只要实现了这个方法,总是可以正确提供
分页显示数据.
//分页查询
public class UserDao{
public int getRows(){
int num = 0;
String sql = "Select count(*) From t_user";
ResultSet rs = DBUtil.executeQuery(sql);
try {
while(rs.next()){
num += rs.getInt(1);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(num);
return num;
}
public List<User> findAll(SplitPage sp) {
List<User> list = new ArrayList<User>();
//获取数据库连接对象
//Connection conn = factory.getConnection();
//Statement st = null;
// ResultSet rs = null;
//在sqlserver数据中分页查询的sql语句,分页的参数来自SplitPage对象
//在MySQL中查询语句为"select * from user limit " + sp.getPageRows()*
//(sp.getCurrentPage()-1) +"," + sp.getPageRows();
//下面这种可能不适用于mysql,一般mysql采用上面那种
String sql = "select * from t_user limit "+ sp.getPageRows()*(sp.getCurrentPage()-1) +"," + sp.getPageRows() ;
//String sql = "select top "+sp.getPageRows()+" * from t_user where id " +
// " not in (select top ("+sp.getPageRows()*(sp.getCurrentPage()-1)+") id " +" from t_user order by id) order by id";
try {
// st = conn.createStatement();
ResultSet rs = DBUtil.executeQuery(sql);
while (rs.next()) {
User user = new User();
user.setId(rs.getInt("id"));
user.setUsername(rs.getString("username"));
user.setPassword(rs.getString("password"));
user.setTitle(rs.getString("title"));
user.setAddress(rs.getString("email"));
user.setEmail(rs.getString("address"));
user.setPhoto(rs.getString("photo"));
user.setMypage(rs.getString("mypage"));
user.setContent(rs.getString("content"));
user.setPdate(rs.getString("pdate"));
user.setAsk(rs.getString("ask"));
user.setQQ(rs.getString("QQ"));
list.add(user);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtil.CloseAll();
}
return list;
}
}
------------------------------------------------------------
4.剩下的工作就是在jsp中分页显示用户列表了,凡是需要分页浏览
显示的数据都可以通过dao和SplitPage对象实现了.
<html>
<head>
<title>My JSP 'userList.jsp' starting page</title>
//这段代码实现在分页中
//切换到分页范围内的任何一个页面
<script type="text/javascript">
function go(){
var goPage=document.all.selectpage.value;
alert("我们将去页面:userList.jsp?flag="+goPage);
document.open("userList.jsp?flag="+goPage,"_self","");
}
</script>
</head>
<%--
spage 是分页对象,保存分页的详细信息,此对象存放在session中
每次查询或显示分页数据时只要设置此对象的当前页就可.
--%>
<jsp:useBean id="spage" class="com.accp.zl.util.SplitPage" scope="session"></jsp:useBean>
<jsp:useBean id="dao" class="com.accp.zl.dao.UserDao" scope="session"></jsp:useBean>
<%
//翻页时的方向值,即SplitPage中请求标识参数
String flag=request.getParameter("flag");
//每次刷新页面时都应当重新获得表中的记录数,
//因为翻页过程中表的记录可能随时都会更新
int totalRows=dao.getRows();//总的记录数
spage.setTotalRows(totalRows);
//重新计算确定当前要显示的页面值,这是一次必要的调用,
//实现了翻页
int currentPage=spage.confirmPage(flag);
spage.setPageRows(3);修改每页显示的记录数,默认3
spage.setTotalRows(totalRows);设定总页数
%>
<body>
<center>
<p><h2>查看用户列表,用户管理</h2>
<br>
<table border="1">
<thead>
<th>编号</th><th>用户名</th><th>出生日期</th><th>爱好</th><th>操作</th>
</thead>
<%
//翻页查询时需要传递翻页对象,翻页对象保存在session中
List<User> list=dao.findAll(spage);
for(User u:list){
%>
<tr>
<td><%=u.getId() %></td>
<td><%=u.getUserName() %></td>
<td><%=u.getBirthday() %></td>
<td><%=u.getInterest() %></td>
<td><a href='modify.jsp?userid=<%=u.getId() %>'>修改 </a><a href='delete.jsp?userid=<%=u.getId() %>'> 删除</a></td>
</tr>
<%} %>
<tr>
<td colspan="5" align="right">
<%--下面页面分页操作,其它数据分页页面复用时拷贝这段
代码就可以了.
--%>
【
<a href="userList.jsp?flag=<%=SplitPage.FIRSTPAGE%>">首页</a>
<a href="userList.jsp?flag=<%=SplitPage.PREVIOUSEPAGE %>">上一页</a>
<a href="userList.jsp?flag=<%=SplitPage.NEXTPAGE %>">下一页</a>
<a href="userList.jsp?flag=<%=SplitPage.LASTPAGE %>">最后页</a>
<select id="selectpage" name="goPage" onchange="javascript:go();">
<%
for(int i=1;i<=spage.getTotalPages();i++){
%>
<option value="<%=i%>" <%=(spage.getCurrentPage()==+i)?"selected='selected'":"" %>><%=i%>/<%=spage.getTotalPages()%>
<%}%>
</select>
】
</td>
</tr>
</table>
</center>
</body>
</html>