100分高分急问!求高手帮忙解决
我在一个函数里执行查询操作,返回结果ResultSet,在后面对ResultSet进行操作。
请问操作完之后该怎样关闭Statement和ResultSet?
因为涉及到大量的查询操作,为了防止内存溢出,需要正确、及时地释放连接。
代码如下所示:
//返回ResultSet结果的函数public java.sql.ResultSet executeQuery(String sexesql) throws SQLException {
java.sql.ResultSet rs = null;
Statement stmtDb = conn.createStatement();
try {
rs = stmtDb.executeQuery(sexesql);
} catch (SQLException e) {
System.err.println("ERROR IN Execute :" + sexesql + " : " + e);
} catch (NullPointerException e) {
}
return (rs);
//调用的代码while (rs.next()) {
long id = rs.getLong(1);
if (!isDeleted(id)) {
PathwayBean pb = new PathwayBean();
pb.selectDataFromDBByID(id);
list.add(pb);
}
}
rs.getStatement().close();//这两行关闭行吗?
rs.close();//这行应该可以省略吧?
我在一个函数里执行查询操作,返回结果ResultSet,在后面对ResultSet进行操作。
请问操作完之后该怎样关闭Statement和ResultSet?
因为涉及到大量的查询操作,为了防止内存溢出,需要正确、及时地释放连接。
代码如下所示:
//返回ResultSet结果的函数public java.sql.ResultSet executeQuery(String sexesql) throws SQLException {
java.sql.ResultSet rs = null;
Statement stmtDb = conn.createStatement();
try {
rs = stmtDb.executeQuery(sexesql);
} catch (SQLException e) {
System.err.println("ERROR IN Execute :" + sexesql + " : " + e);
} catch (NullPointerException e) {
}
return (rs);
//调用的代码while (rs.next()) {
long id = rs.getLong(1);
if (!isDeleted(id)) {
PathwayBean pb = new PathwayBean();
pb.selectDataFromDBByID(id);
list.add(pb);
}
}
rs.getStatement().close();//这两行关闭行吗?
rs.close();//这行应该可以省略吧?
stmtDb.close();//关闭操作数据库对象
按照jdbc接口要求:
关闭connection后,statement及resultset会自动关闭
或者关闭statement后resultset会自动关闭。
具体实现是数据库厂商实现的。
不然就没办法及时关闭啦!
public void executeQuery(String sexesql) throws SQLException {
java.sql.ResultSet rs = null;
Statement stmtDb = conn.createStatement();
try {
rs = stmtDb.executeQuery(sexesql);
call1(rs); // 所有的调用
call2(rs);
call3(rs);
} catch (SQLException e) {
System.err.println("ERROR IN Execute :" + sexesql + " : " + e);
} catch (NullPointerException e) {} finally { // 这里关闭
try {
rs.close();
} catch (Exception ex) {}
}
// return (rs);
}
stmtDb.close();//关闭操作数据库对象
conn.close();//关闭数据库连接对象 应该是这个顺序吧!!!
rs.getStatement().close();//这个是官Statement
rs.close();//这个是关闭ResultSe
2.如果你的代码有异常抛出的话,你的Statement和ResultSet也都关不掉。
3.最后ResultSet最好不要当成任何返回值返回。应该直接返回VO,数据对象。
改进方法
比如一个数据对象 Actor类。可以根据自己的需要更改。public class Actor { private Long id;
private String firstName;
private String lastName;
public String getFirstName() {
return this.firstName;
}
public String getLastName() {
return this.lastName;
}
public Long getId() {
return this.id;
}
// 省略存取方法}
调用代码注意要返回数据对象。下面的代码是最简单最基本的调用JDBC的方法。如果引入连接池呀,Hibernate或Spring会简化许多。public List<Actor> executeQuery(String sexesql) throws SQLException {
List<Actor> actorList = new ArrayList<Actor>();
Connection con = null;
Statement stmt = null;
ResultSet rs = null
try {
con = DriverManager.getConnection(url, "sunny", "");
stmt = con.createStatement();
rs = stmtDb.executeQuery(sexesql);
Actor actor = null;
while (rs.next()) {
actor = new Actor();
actor.setId(rs.getLong("id"));
actor.setFirstName(rs.getString("firstName"));
actor.setLastName(rs.getString("lastName"));
actorList.add(actor);
}
}catch (Exception e) {
System.err.println("ERROR IN Execute :" + sexesql + " : " + e);
}finally{ //在这里关闭资源才是正解
try{
if(rs != null){
rs.close();
}
if(stat != null){
stat.close();
}
if(conn != null){
conn.close();
}
}catch(Exception ignor){ //忽略这里的异常
}
}
return actorList;
}
try{
if(conn != null)
conn.close();
}catch(Exception e){
}
易载--个人网上资料收集必备工具。选中想收藏的文字(图片),右键选“收录到易载”,搞定!
close
void close()
throws SQLException立即释放此 ResultSet 对象的数据库和 JDBC 资源,而不是等待该对象自动关闭时发生此操作。
注:当生成 ResultSet 对象的 Statement 对象关闭、重新执行或用来从多个结果的序列检索下一个结果时,该 Statement 对象会自动关闭 ResultSet 对象。垃圾回收 ResultSet 对象时它也会自动关闭。
try
{
con =
stmt =
rs =
}
catch (Exception e)
{
}
finally
{
try
{
if(rs != null)
{
rs.close();
rs=null; }
if(stat != null)
{
stat.close();
stat=null; }
if(conn != null)
{
conn.close();
conn=null; }
}catch(Exception ignor){ }
}
package com.xiaolin.database;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;public class DBManager {
private Connection cnn;
private PreparedStatement stmt;
private ResultSet rs;
public void OpenDB(){
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
cnn=DriverManager.getConnection("jdbc:odbc:test","sa","");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public ResultSet Query(String sql,Object[] objs){
try {
stmt=cnn.prepareStatement(sql);
for (int i = 0; i < objs.length; i++) {
stmt.setObject(i+1, objs[i]);
}
rs=stmt.executeQuery();
} catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
}
return rs;
}
public int Update(String sql,Object[] objs){
int alterCount=0;
try {
stmt=cnn.prepareStatement(sql);
for (int i = 0; i < objs.length; i++) {
stmt.setObject(i+1, objs[i]);
alterCount=stmt.executeUpdate();
}
} catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
}
return alterCount;
}
public void CloseDB(){
try {
rs.close();
stmt.close();
cnn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
*
* @param rs ResultSet
* @param st Statement
* @param conn Connection
*/
public void closeConnections(ResultSet rs, Statement st, Connection conn)
{
if (rs != null)
{
try
{
rs.close();
}
catch (SQLException e)
{
}
}
if (st != null)
{
try
{
st.close();
}
catch (SQLException e)
{
}
}
if (conn != null)
{
try
{
conn.close();
}
catch (SQLException e)
{
}
}
}
比方在java_web中,按你一次请求结束以后再关闭连接
{
System.err.println("ERROR IN Execute :" + sexesql + " : " + e);
} catch (NullPointerException e)
{}
finally
{
try
{
rs.close();
} catch (Exception e)
{}
}
在catch后加finally代码块,无论有没有异常,都会执行 ,支持6楼
我的Connection用的是Singleton模式,并不是每种(批)查询完都关闭。
请问这种设计好吗?还是应该每批查询完成之后,关闭所有的ResultSet、Statement和Connection,好呢?public static PathwayDBUtil getInstance(String name){
if (dBUtilInstace == null){//用Singleton模式,只有一个实例
dBUtilInstace = new PathwayDBUtil();
url="jdbc:sqlserver://192.168.2.5:1433;DatabaseName="+name;
dBUtilInstace.openConn();
}
return dBUtilInstace;
}
private void openConn() {//打开数据库连接
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
conn = DriverManager.getConnection(url, user, pwd); } catch (Exception e) {
e.printStackTrace();
}
}
public void closeConn() {//在所有批次查询都查完后最后关闭数据库连接
try {
if (conn == null) {
return;
}
conn.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
conn.close();
} catch (Exception e) {
}
}
}
1. 哪儿拿到的哪儿关闭。
2. 关闭放 finally 里免得抛异常关闭执行不到。
3. 数据流动方向 DB -> RS -> Bean -> View。
一般关的时候习惯于在finally{}里按resultset, statement,connection关
即使关闭connection后,statement及resultset会自动关闭
看你的代码,你的dBUtilInstace 是Singleton的
你的connection不是Singleton的。
rs.close();
con.close();
}
{
try
{
st.close();
}catch(Exception e)
{
}
try
{
con.close();
}catch(Exception e)
{
}
}
public static void close(ResultSet rs, Statement st, Connection con)
{
try
{
rs.close();
}catch(Exception e)
{
}
close(st, con);
}
单独写一个类,专门用于连接、关闭的util
2。如果只是想释放资源可以直接将rs和st赋值为null。
3。建议写个JDBCUtil类,实现代码复用。
if (dbc != null) {
try {
DBHT.remove(dbc.globeID);
useCnt--;
if (dbc.connection != null) {
dbc.connection.close();
String[] msg = { "DBFactory", "closeConnection",
dbc + " 关闭成功" };
TLoger.logDebug("2003", msg);
} else {
String[] msg = { "DBFactory", "closeConnection",
dbc + " 不存在联接" };
TLoger.logDebug("2003", msg);
} } catch (SQLException ex) {
String[] err = { "DBFactory", "closeConnection", dbc + " 关闭失败" };
TLoger.logErr("3300", err, ex);
}
}
}
if(!conn.isClosed)
{
conn.closed();
}
rs.close();//这行应该可以省略吧?
==================================
最好是这样:
if(rs !=null){
try{
rs.close();
}catch(Exception e){
System.out.println(e);
}
}