想把数据库中的几条记录显示出来,结果折腾了半天也没弄成,总找不到原因,后来干脆就在读数据之前用了个rs.next(),在读取数据,这次没问题了!

      后来才发现 

      ResultSet 维护指向其当前数据行的光标。每调用一次 next() 方法,光标向下移动一行。最初它位于第一行之前,因此第一次调用 next 将把光标置于第一行上,使它成为当前行。随着每次调用 next 导致光标向下移动一行,按照从上至下的次序获取 ResultSet 行。

 

1.  我们通过JDBC查询,是否一次是把所有的结果集查询出来后放到ResultSet中。

2.  在调用ResultSet.next()方法的时候,是否还会和数据库交互。

 

      其实在以前我一直认为当statement执行完sql语句后,它会把结果集保存到ResultSet中,然后关闭这个cursor,当实际上并不是这样的。

 

      今天写的一个javabean:

package student;
import java.sql.*;
public class conn
{
 String sDBDriver="sun.jdbc.odbc.JdbcOdbcDriver";
 String sConnStr="jdbc:odbc:student";
 Connection connect=null;
 Statement stmt=null;
 ResultSet rs=null;
 String str="";
 public conn()
 {
  try
  {
   Class.forName(sDBDriver);
  }
  catch(java.lang.ClassNotFoundException e)
  {
   System.err.println(e.getMessage());
  }
  try
  {
   connect=DriverManager.getConnection(sConnStr);
   stmt=connect.createStatement();
  }catch(Exception e){
   e.printStackTrace();
   }
 }
 public ResultSet executeQuery(String sql)
 {
  try
  {
   rs=stmt.executeQuery(sql);
  }
  catch(SQLException ex)
  {
   System.err.println(ex.getMessage());
  }
  return rs;
 }
 
 public int executeUpdate(String sql)
 {
  int result=0;
  try
  {
   result=stmt.executeUpdate(sql);
   
  }
  catch(SQLException ex)
  {
   System.err.println(ex.getMessage());
  }
  
  return result;
 }
}

开始把

Statement stmt=connect.createStatement();

 

放入了函数

 

public ResultSet executeQuery(String sql){}

 

中,想到每次调用都会创建一个新的stmt变量,这样太浪费资源,于是就把

stmt=connect.createStatement();

 

放入构造函数中,使用的时候直接使用该实例即可。在jsp页面中使用该javabean。

 

<%@ page contentType="text/html;charset=GBK" %>
<%@ page language="java" import="java.sql.*" %>
<%@ page import="java.lang.Math.*"%>
<jsp:useBean id="conn" scope="session" class="student.conn"/>
<%!
   ResultSet rs=null;
   ResultSet rsTmp=null;
   String sql="";
   int PageSize=3;
   int Page=1;
   int totalPage=1;
   String str="";

   public String ShowOnePage(ResultSet rs,int Page,int Pagesize)
   {
      str="";
      try
      {
         for(int i=0;i<(Page-1)*Pagesize+1;i++)
           rs.next();
      }
      catch(SQLException e)
      {
          e.printStackTrace();
      }
      for(int iPage=1;iPage<=Pagesize;iPage++)
      {
          str+=RsToGbook(rs);  
          try{
            if(!rs.next())  break;
          }
          catch(Exception e)
          {
              e.printStackTrace();
          } 
      }
      return str; 
   }

  public String RsToGbook(ResultSet rs)
  {
     String tt="";
     try{
        tt+="<tr>";
        tt+="<td>"+rs.getString("name")+"</td>";
        tt+="<td>"+rs.getString("sex")+"</td>";
        tt+="<td>"+rs.getInt("score")+"</td>";
        tt+="</tr>";
      }
      catch(Exception e){}
     return tt;
  }

%>

<%

sql="select * from table1";
   try{
       rs=conn.executeQuery(sql);
   }catch(Exception e){
      out.println("访问数据库出错!");
   }
%>

<html>
   <head>
     <title>分页访问数据库</title>
   </head>
   <body bgcolor="#ffffff">
      <h2 align="center">jsp中的分页控制</h2>
      <hr>
      <center>
          <table border>
             <tr bgcolor="#ccccff">
                 <td>
                     <div align="center"><font color="#ff0033"><b>姓名</b></font></div>
                 </td>
                 <td>
                     <div align="center"><font color="#ff0033"><b>姓别</b></font></div>
                 </td>
                 <td>
                     <div align="center"><font color="#ff0033"><b>分数</b></font></div>
                 </td>
             </tr>

             <%
                int totalrecord=0;
                try{
                   rsTmp=conn.executeQuery("select count(*) as mycount from table1");
                   rsTmp.next();
                   totalrecord=rsTmp.getInt("mycount");
                }catch(SQLException e){}

                out.println("totalrecord="+totalrecord);    

                if(totalrecord%PageSize==0)
                   totalPage=totalrecord/PageSize;
                else
                   totalPage=totalrecord/PageSize+1;
      out.println("totalPage:"+totalPage);            
                if(totalPage==0)  totalPage=1;               

                try{
                    if(request.getParameter("Page")==null||request.getParameter("Page").equals(""))
                       Page=1;
                    else
                       Page=Integer.parseInt(request.getParameter("Page"));
                }catch(java.lang.NumberFormatException e){
                    Page=1;
                  }
               if(Page<1) Page=1;
               if(Page>totalPage) Page=totalPage;
               out.println(ShowOnePage(rs,Page,PageSize));
            %>

        </table>

        <form action=page.jsp method=get>
          <%
              if(Page!=1){
                  out.println("<a href="page.jsp?Page=1" mce_href="page.jsp?Page=1">第一页</a>");
                  out.println("<a href="page.jsp?Page=" mce_href="page.jsp?Page=""+(Page-1)+">上一页</a>");     
               }
              else
              {
                  out.println("第一页");
                  out.println("上一页");
              }   
              if(Page!=totalPage){
                   out.println("<a href="page.jsp?Page=" mce_href="page.jsp?Page=""+(Page+1)+">下一页</a>");
                   out.println("<a href="page.jsp?Page=" mce_href="page.jsp?Page=""+totalPage+">最后一页</a>");
              }
              else
              {
                   out.println("下一页");
                   out.println("最后一页");
              }
              try{
                rs.close();
              }catch(Exception e){out.println("colse exception");};
              //conn.connClose();
          %>  
          <p>  输入页数:<input type="text" name="Page" size="3">页数:<font color="red"><%=Page%>/
               <%=totalPage%></font>
          </p>
         </form>
      </center> 
      <hr>
   </body>
</html>

 

      该jsp页面在运行时会抛出ResultSet is colsed异常,注意蓝色代码部分调用了executeQuery();方法,此时javabean中执行的是executeQuery(select * from table1);返回的数据集“rs”也是该语句执行的结果。

      执行到蓝色代码时也调用了executeQuery();此时执行的是调用了executeQuery(select count(*) as mycount from table1);返回的数据集rsTmp就是该语句的执行结果。 

      注意:两次使用了同一个stmt的executeQuery()方法。

Statement stmt=connect.createStatement();放入了函数public ResultSet executeQuery(String sql)中就不会出现这种问题。

      通过上面分析,我们可以的出结论通过JDBC查询结果集不是直接放到ResultSet中,ResultSet存在的可能是结果集的指针。我们在使用ResultSet时仍然需要和数据库交互。