这种model1模式页面显示和分页的业务逻辑混合在一起.比较简单.
但是代码可读性很差,而且不容易维护.
在韩顺平SERVLET教程的第四讲中有明确的说明.
晚上弄清楚算法,贴过来.
需要4个参数
pageSize --> 用户指定
pageNow --> 用户选择
rowCount --> 从表中查询出来
pageCount --> 计算出来
pageCount的计算方法
if (rowCount % pageSize == 0) {
pageCount = rowCount / pageSize;
}else {
pageCOunt = rowCount / pageSize + 1;
}
说明:如果用户的表中有9条记录,即rowCount = 9,pageSize = 3的话,那么pageCount就为3,正确
如果pageSize = 4,rowCount / pageSize取整也是2,+1后共3页.正确.
针对上面的算法,很自然的想到下面的SQL语句
select 字段表名 from 表名 where id bwteen ? and ?
比如显示第三页(pageSize = 3)的话,那么就是
select * from user where userId bwteen 7 and 9;
但是有这样一个问题,如果userId被删除掉或者不连续的话,那么返回的结果集就是错误的.
下面列出常见的几个数据库的分页SQL语句
MySQL数据库
My sql数据库最简单,是利用mysql的LIMIT函数,LIMIT [offset,] rows
从数据库表中M条记录开始检索N条记录的语句为:
SELECT * FROM 表名称 LIMIT M,N
例如从表Sys_option(主键为sys_id)中从10条记录还是检索20条记录,语句如下:
select * from sys_option limit 10,20
例如要从"品种"表里检索,语句为
sql = "select * from pinzhong limit "+pageSize+","+pageSize*(pageNow-1)+" " ;
在我们使用查询语句的时候,经常要返回前几条或者中间某几行数据,这个时候怎么办呢?不用担心,mysql已经为我们提供了这样一个功能。
LIMIT 子句可以被用于强制 SELECT 语句返回指定的记录数。LIMIT 接受一个或两个数字参数。参数必须是一个整数常量。如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目。初始记录行的偏移量是 0(而不是 1): 为了与 PostgreSQL 兼容,MySQL 也支持句法: LIMIT # OFFSET #。
SQL Server
从数据库表中的第M条记录开始取N条记录,利用Top关键字:注意如果Select语句中既有top,又有order by,则是从排序好的结果集中选择:
SELECT*
FROM(SELECTTopN*
FROM(SELECTTop(M+N-1)*FROM表名称Orderby主键desc)t1)t2
Orderby主键asc
例如从表Sys_option(主键为sys_id)中从10条记录还是检索20条记录,语句如下:
SELECT*
FROM(SELECTTOP20*
FROM(SELECTTOP29*FROMSys_optionorderbysys_iddesc)t1)t2
Orderbysys_idasc
Oralce数据库
从数据库表中第M条记录开始检索N条记录
SELECT*
FROM(SELECTROWNUMr,t1.*From表名称t1whererownum<M+N)t2
wheret2.r>=M
例如从表Sys_option(主键为sys_id)中从10条记录还是检索20条记录,语句如下:
SELECT*
FROM(SELECTROWNUMR,t1.*FromSys_optionwhererownum<30)t2
Wheret2.R>=10
在mysql数据库中分页实例
response.setContentType("text/html;charset=gbk") ; request.setCharacterEncoding("gbk") ; PrintWriter pw = response.getWriter() ; //定义连接数据库所需要的几个常量 final String DBDriver = "com.mysql.jdbc.Driver"; final String DBURL = "jdbc:mysql://localhost:3306/test"; final String user = ""; final String password = ""; Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { //定义分页所需要的几个变量 int pageCount = 0; int pageSize = 3; int rowCount = 0; int pageNow = 1; //动态的接收pageNow,实现分页的实时功能 String spageNow = request.getParameter("pageNow") ; if(spageNow != null) { pageNow = Integer.parseInt(spageNow) ; } Class.forName(DBDriver).newInstance(); conn = DriverManager.getConnection(DBURL, user, password); String sql_count = "select count(*) from pinzhong"; //取得当前表中总的记录数 ps = conn.prepareStatement(sql_count); rs = ps.executeQuery(); //取得rowCount if (rs.next()) { rowCount = rs.getInt(1); } //计算pageCount if ((rowCount % pageSize) == 0) { pageCount = rowCount / pageSize; } else { pageCount = rowCount / pageSize + 1; } System.out.println("pageSize->" + pageSize) ; System.out.println("pageCount->" + pageCount) ; System.out.println("pageSize*(pageNow-1)->" + pageSize*(pageNow-1)) ; System.out.println("spageNow->" + spageNow) ; String sql_do = "select * from pinzhong limit "+pageSize*(pageNow-1)+" , "+pageSize+" " ; ps = conn.prepareStatement(sql_do); rs = ps.executeQuery(); pw.println("共有" + pageCount +"页") ; pw.println("<table border=1>") ; pw.println("<tr><th>id</th><th>品种</th></tr>") ; while(rs.next()) { pw.println("<tr>") ; pw.println("<td>"+rs.getInt(1)+"</td>") ; pw.println("<td>"+rs.getString(2)+"</td>") ; pw.println("</tr>") ; } pw.println("</table>") ; //显示上一页 if(pageNow != 1) { pw.println("<a href=wel?pageNow="+(pageNow-1)+">上一页</a>") ; } for(int i = pageNow; i <= pageNow+4 ; i++) { pw.println("<a href=wel?pageNow="+i+">"+i+"</a>") ; } //显示下一页 if(pageNow < pageCount){ pw.println("<a href=wel?pageNow="+(pageNow+1)+">下一页</a>") ; } } catch (Exception e) { e.printStackTrace() ; } finally { try { if (rs != null) { rs.close() ; rs = null ; } if ( ps != null) { ps.close() ; ps = null ; } if (conn != null) { conn.close() ; conn = null ; } }catch(SQLException e) { e.printStackTrace() ; } }