JSP 分页显示数据 (Oracle)

要实现分页,首先我们要做的就是如何来编写SQL语句,网上也有很多,大家可以搜一下.在这里,我们使用一种比较常用的方式来编写SQL语句。代码如下:

----分页显示
select * from (select rownum as r,t.* from 
                            (select emp.* from emp order by hiredate desc) t where rownum<=10)
                                      where r>5;

查询的结果如下:


这个SQL,使用了三层嵌套的查询方式:

1)最内层的select 语句

      最内层的Select语句是一条普通的查询语句,它的执行结果,将是emp表中的所有数据按照受雇日期降序排列.

2)第二层的select 语句

     这一层的Select 语句使用了rownum,这条语句的执行结果就是从最内层语句的查询结果中按照rownum的顺序取出前10条.实际上,中间层的select 语句的执行结果是限制查询记录数量的最大记录数。

3)最外层的select 语句

     既然中间层的select语句控制了查询过程中数据的最大记录数,那么最外层的select语句就要控制查询过程中的最小记录数。由此可以得出的结论是:上面SQL的执行结果就是查询emp表中第6条~~~第10条的数据记录.

 

通过以上的分析,我们了解了在Oracle众分页查询的实现原理。现在要做的就是在第二层和最外层将数据库记录的最大值和最小值替换成我们需要的值。

 

在分页显示时,每页显示数据量是固定的,假设每页显示10条数据,第1页的编号就是1到10,当用户单击第二页时显示的数据编号为11--20,以此类推,限制最后一页。

这样我们可以总结出一个规律:

                           每页显示的第一条数据行号应该等于 【每页显示的数据量*(当前页码-1)+1】。-----可以看出上面的SQL的最外层 R>【每页显示的数据量*(当前页码-1)】,这样行号才匹配。

                           每页显示的最后一条数据行号等于【每页显示的数据量*当前页码】。         

经过分析,我们对上面的SQL进行修改,得到下面的代码:

    String sql="select * from (select rownum as r,t.* from " +
          		                      "(select emp.* from emp order by hiredate desc) t where  rownum<="+(pageSize*pageIndex)
          		                      +") where r>"+pageSize*(pageIndex-1);


上面就是下面将要使用的分页查询的SQL语句,并使用到了两个变量,分别是pageSize和pageIndex,其中pageSize表示每页显示的数据条数,而pageIndex变量表示当前页的页码。


下面的代码是简单的实现了Oracle分页查询在JSP分页展示数据的实现。写的比较简单,在JSP中嵌套java代码比较乱,建议使用Servlet。

首先,需要编写一个是实现分页查询的java类,没有进行特殊的整合,凑合着吧,原理就是这样:

package com.dao;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class EmpDao {
    private Connection conn=null;
    private PreparedStatement psmt=null;
    private ResultSet rs=null;
    /**
     * 获得数据库连接
     */
    private void openConn(){
		//首先定义下连接数据的URL、用户名、密码
		String url="jdbc:oracle:thin:@127.0.0.1:1521:orcl";
		String user="scott";
		String password="yulei123";
		 try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
	    	conn=DriverManager.getConnection(url,user,password);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
    }
    /**
     * 获得所有员工数据
     */
    public List getAllemp(){
    	List list=new ArrayList();
    	openConn();
    	String sql="select * from emp order by hiredate desc";
        try {
			psmt=conn.prepareStatement(sql);
		    rs=psmt.executeQuery();
		    while(rs.next()){
		    	Map emps=new HashMap();
		    	emps.put("empno", rs.getString("empno"));
		    	emps.put("ename",rs.getString("ename"));
		    	emps.put("sal", rs.getString("sal"));
		    	list.add(emps);
		    }
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return list;
    } 
    /**
     *  获取第几页的数据
     */
    public List getAllempByPage(int pageSize,int pageIndex){
          List list =new ArrayList();
          String sql="select * from (select rownum as r,t.* from " +
          		                      "(select emp.* from emp order by hiredate desc) t where  rownum<="+(pageSize*pageIndex)
          		                      +") where r>"+pageSize*(pageIndex-1);
           try {
			  psmt=conn.prepareStatement(sql);
			  rs=psmt.executeQuery();
			  while(rs.next()){
				  Map map=new HashMap();
				  map.put("empno", rs.getString("empno"));
				  map.put("ename",rs.getString("ename"));
				  map.put("sal", rs.getString("sal"));
				  list.add(map);
			  }
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return list;
    }
    /**
     *  获取员工的总数
     * 
     */
    public int countEmp(){
    	int count=0;
    	String sql="select count(*) from emp";
    	openConn();
    	try {
			psmt=conn.prepareStatement(sql);
			rs=psmt.executeQuery();
			while(rs.next()){
				count=rs.getInt(1);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return count;
    }
    /**
     *  根据每页显示的数量,得到总页数
     */  
    public int getTotalPage(int pageSize){
    	int totalPage=countEmp();
    	return (totalPage%pageSize==0)?(totalPage/pageSize):(totalPage/pageSize+1);
    }
}


接下来就是编写JSP文件,命名为pageTest.jsp.

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@page import="com.dao.EmpDao"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>Oracle分页</title>
  </head>
  <body>
      <%
        EmpDao ed=new EmpDao();
        int pageSize=4;//每页显示的记录
        int totalpages=ed.getTotalPage(pageSize); //最大页数
        String currentPage=request.getParameter("pageIndex"); //获得当前的页数,即第几页
        if(currentPage==null){
        	currentPage="1";
        }
        int pageIndex=Integer.parseInt(currentPage);
        //添加逻辑判断,防止页数异常
        if(pageIndex<1){
        	pageIndex=1;
        }else if(pageIndex>totalpages){
        	pageIndex=totalpages;
        }
       List list= ed.getAllempByPage(pageSize,pageIndex);  //返回特定页数的数据
      %>
      <!-- 循环显示员工的数据 -->
       <table border="1">
          <tr>
             <td>员工工号</td>
             <td>员工姓名</td>
             <td>员工工资</td>
          </tr>
      <%
        Map map=null;
        for(int i=0;i<list.size();i++){
        	map=(Map)list.get(i);
       %> 
                 <tr>
                    <td><%=map.get("empno") %></td>
                    <td><%=map.get("ename") %></td>
                    <td><%=map.get("sal")%></td>
                 </tr>
      <% }%>
    </table> 
         <a href="pageTest.jsp?pageIndex=1">首页</a> 
         <a href="pageTest.jsp?pageIndex=<%=pageIndex-1 %>">上一页</a>
         <a href="pageTest.jsp?pageIndex=<%=pageIndex+1 %>">下一页</a>
         <a href="pageTest.jsp?pageIndex=<%=totalpages%>">末页</a>
         <br/>
         <p style="color:red"">当前页数:<%=pageIndex%></p>
  </body>
</html>


最后,我们在浏览器访问这个JSP文件.(http://127.0.0.1:7001/jsp/day4/pageTest.jsp).得到下面的显示效果:

当我们单击下一页或上一页的时候会显示不同的数据:

 

分页的大概原理就是这样,有什么疑问的可以留言,谢谢!

 

 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值