想把数据库中的几条记录显示出来,结果折腾了半天也没弄成,总找不到原因,后来干脆就在读数据之前用了个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时仍然需要和数据库交互。