板桥你说:“数据库关闭之后可以使用resulset访问,我以前一直这么做,我都是使用PrepareStatement”。为什么我的代码在jsp页面里提

smallduzi 02-10-16

板桥你说:“数据库关闭之后可以使用resulset访问,我以前一直这么做,我都是使用PrepareStatement”。为什么我的代码在jsp页面里提示数据库已关闭。

SQLHelper.java
package com.pingod.database;

import java.sql.SQLException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.*;
import com.pingod.sql.ConnectionPool;

public final class SQLHelper {

private ConnectionPool pool = null;
private Connection con = null;
private PreparedStatement pstmt = null;
private ResultSet rs = null;

public SQLHelper(){
pool = ConnectionPool.getInstance();
}

public ResultSet userDbQuery() throws SQLException{
con = pool.getConnection();
String sql = "select tempid,username,password from tempuser where 1 = ?";
pstmt = con.prepareStatement(sql);
pstmt.setInt(1,1);
rs = pstmt.executeQuery();
pstmt.close();
//我把这行和下面那行注释掉query.jsp就可以显示了,否则提示[Microsoft][SQLServer JDBC Driver]Object has been closed.

con.close();
return rs;
}


}

query.jsp
<%@ page contentType=
"text/html; charset=gb2312"%>
<%@ page import=
"java.util.*, java.sql.*, java.text.*"%>
<%@ page import=
"com.pingod.database.SQLHelper"%>
<%!
ResultSet rs = null;
%>
<HTML>
<HEAD>
<TITLE></TITLE>
</HEAD>
<BODY leftmargin=
"5" topmargin="8" bgcolor="#FFFFFF" text="#000000">
<table width=
"100%" border="1" cellspacing="0" cellpadding="0">
<tr>
<td>id</td>
<td>username</td>
<td>password</td>
</tr>
<%
SQLHelper sqlHelper = new SQLHelper();
rs = sqlHelper.userDbQuery();
while(rs.next()){
String id = rs.getString(1);
String username = rs.getString(2);
String password = rs.getString(3);
%>
<tr>
<td><%=id%></td>
<td><%=username%></td>
<td><%=password%></td>
</tr>
<%
}
%>
</table>
</BODY>
</HTML>

我的代码那里错了,请多指教!

iceant
2002-10-16 17:53

这是很有可能的,因为不同的 JDBC 实现方式是不同的.
就好像,不同的 C 编译器,编译的方式是不同的.

有空你自己写写 JDBC 就会明白了.或参照 PoolMan 的源代码,
你也会有很大提高

smallduzi
2002-10-17 08:22

"或参照 PoolMan 的源代码,"哪里有

blues
2002-10-17 12:07

可能是benq的一个笔误吧。我同时在oracle,mysql,sybase上测试这个问题,结果都是一样。
这些DB厂商提供的JDBC Driver 都是这样做的:关闭statement后会把相关的resultset资源释放,因此如果想要使用rs.next()获取数据,则必须保持连接。

benq所说的那种情况,我想只可能是使用Connection Pool的时候。比如PoolMan。PoolMan是一个不错的Connection Pool工具。它的Connection的close()方法是这么做的:

if (connection != null)
return connection to Pool


在这里,Connection返回到连接池而已,没有真正调用close()方法,因此没有释放resultset资源。

PoolMan本身也实现了JDBC接口。但很有问题,因为它所管理的底层数据库的实现机制不同。举个例子,mysql的Connection在 wait_timeout时间之后自动关闭。因此,PoolMan的连接池中mysql Connection总要在小于wait_timeout时间之前重启动该连接。而对于oracle的Connection没有这个问题。(Pool中的 oracle 的Connection 永远不会自动关闭)

总之,既然JDBC接口对Close()方法的实现不同,那就应该避免使用这些特性。

smallduzi
2002-10-17 13:58

哪我觉得,它是一个bug.看来只能想别的方法了.
我刚找到http://jakarta.apache.org/中有一个commons-beans.jar哪里有这方面的类.

2Go 1 2 下一页