诚心求教,如何关闭JDBC中一个connection的所有resultset和statement

时间:2022-01-06 03:00:00
请问各位,如何关闭JDBC中一个connection的所有resultset和statement

我知道直接关闭connection也可以实现,但是因为我的程序需要不停的操作数据库,是一个电信项目,所以connection要一直保持,不去关闭它,不然开销太大,而且因为需要频繁的创建resultset和statement,如果一个个关闭太麻烦了,能否在一个操作循环完后,在一个地方关闭掉一个connection的所有resultset和statement呢?

33 个解决方案

#1


在finally里关resultset和statement不可以?

#2


感觉你的代码结构有问题,尝试重构下

#3


页面上:
resultset.close();
 resultset=null;
 (statement) :opa
 opa.free();
在连接库的类里面:
// 进行数据库连接释放
public boolean free() {
try {
count--;

if (stmt != null) {
if (!stmt.getConnection().isClosed()) {
stmt.close();

}

}
if (connect != null) {
if (!connect.isClosed())
connect.close();
}
return true;
} catch (Exception e) {
return false;
}

}

#4


一种是通过项目组内部开发约束,约束你的开发人员用完statement、resultset之后必须在finally中关闭;

第二种方式是对操作数据库的方式都用Template Design Pattern封闭,类似Spring的JdbcTemplate那样,开发人员不用编写大量重复的关闭代码

第三种方式可以通过Adapter模式二次封装特定的JDBC包的Connection、Statement对象,实现Connection、Statement接口,分别让你的statement、resultset对象在Connection、Statement中可控制,比如Connection发放得一个Statement对象时,在你自定义的Connection类对象中可以保留一个这个对象的引用
, 之后可以通过调用方法connection.closeAllStatement(),遍历你所发放在外的Statement,对其发放在外的resultset对象关闭,之后再关闭自身,这样就能达到你所要的效果。也可以调用调用statement.closeAllResultset()对象来关闭这个statement发放在外的所有的resultset对象了。

#5


还是J2SE / 基础类的人比较好啊,这个问题刚开始发到J2SE / 扩展类好几天都没人回复,可能这个问题太简单?J2SE / 扩展类里的高人都不屑回答?

to gongyali2005(JAVA 民工)
你说的我试过,但是有问题
我之前发过这个问题,但是一直没有得到满意的答案,所以我就换了个问题,贴下之前的那个问题,其实现在这个问题就是因为要解决那个问题的
最近在做的一个程序,遇到了一个JDBC方面的问题,我的代码如下
 public  ResultSet  executeSql(String sqlstr)
  {
     Statement stmt = null;
     ResultSet  rs = null;

     try
     {
       stmt=conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
       rs=stmt.executeQuery(sqlstr);
       DebugLog.logger.log(Level.INFO,"获取数据集成功");
       return rs;
     }
     catch(SQLException e)
     {
       DebugLog.logger.log(Level.WARNING,"获取数据集时出现错误");
       DebugLog.logger.log(Level.WARNING,e.getMessage());
       try{
       conn.rollback();
       }
       catch(SQLException i)
   {
       DebugLog.logger.log(Level.WARNING,"回滚数据集时出现错误");
       DebugLog.logger.log(Level.WARNING,i.getMessage());
   }
       return null;
     }
     catch(Exception cnfe){
     DebugLog.logger.log(Level.WARNING,"获取数据集时出现错误");
     DebugLog.logger.log(Level.WARNING,cnfe.getMessage());
     return null;
     }  }
这是我之前写的一段JDBC操作数据库的代码,但是主程序运行一段时间出现这样的异常ora-01000: maximum open cursors exceeded.到网上查了下,说是已经达到一个进程打开的最大游标数,Java代码在执行conn.createStatement()和conn.prepareStatement()的时候,实际上都是相当与在数据库中打开了一个cursor。
尤其是,如果你的createStatement和prepareStatement是在一个循环里面的话,就会非常容易出现这个问题。因为游标一直在不停的打开,而且没有关闭,所以说,最好在执行了一次executeQuery、executeUpdate等之后,如果不需要使用结果集(ResultSet)的数据,就马上将Statment关闭。然后我的代码改进如下
 public  ResultSet  executeSql(String sqlstr)
  {
     Statement stmt = null;
     ResultSet  rs = null;

     try
     {
       stmt=conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
       rs=stmt.executeQuery(sqlstr);
       DebugLog.logger.log(Level.INFO,"获取数据集成功");
       return rs;
     }
     catch(SQLException e)
     {
       DebugLog.logger.log(Level.WARNING,"获取数据集时出现错误");
       DebugLog.logger.log(Level.WARNING,e.getMessage());
       try{
       conn.rollback();
       }
       catch(SQLException i)
   {
       DebugLog.logger.log(Level.WARNING,"回滚数据集时出现错误");
       DebugLog.logger.log(Level.WARNING,i.getMessage());
   }
       return null;
     }
     catch(Exception cnfe){
     DebugLog.logger.log(Level.WARNING,"获取数据集时出现错误");
     DebugLog.logger.log(Level.WARNING,cnfe.getMessage());
     return null;
     }finally{
     try{
     if(rs != null){
     rs.close();
     }
     if(stmt != null){
     stmt.close();
     }
     }catch(SQLException j){
     DebugLog.logger.log(Level.WARNING,"关闭数据集时出现错误");
     DebugLog.logger.log(Level.WARNING,j.getMessage());
     }     
     }
  }
但是这段代码的问题是,每次取这段代码执行SQL后返回的记录集,就会抛出一个信息为null的异常,我猜想是上面这个函数没返回任何记录集,rs是null的?
实在不知道什么原因,求高人指教,是什么原因?应该如何修改?谢谢了,我分不多,实在抱歉

#6


to zl8108304732() 我现在做的不是web程序哈,是在UNIX上后台运行的一个进程,现在做的项目是电信的一个新业务,这个进程需要在后台不停的处理数据,本来想用C来写的,因为我们公司之前的都是用C来实现,但是不知道怎么用C连接SQLSERVER,之前公司的都是连的oracle,所以改用java了,而且java操作数据库也比c简单的多,这个程序对性能也没太高的要求
不过还是谢谢你

to XinZi(新子),谢谢你哈,恩,你的第一种方式通过上面的代码看出,是不行的,因为要返回rs
现在这个新业务除了因为有些statement用完没有关闭,运行时间长了会出现ora-01000: maximum open cursors exceeded.,业务处理上已经测试没什么问题了,所以不想大改了,否则还得重新测试?电信的这个新业务马上就要推出去了
我试下你的第三种方式

#7


路过学习一下!

#8


有没有更好更简单的解决方法?比如connection的某个方法可以关闭该connection的所有创建的statement?

#9


调用Connection.close()关闭所有Statment和ResultSet,调用Statment.close()关闭所有ResultSet。
"resultset.close();"后面的“ resultset=null;”是多于的。"
Statment变量用完得关闭,特别是变量被多次赋值(stmt=conn.createStatement()),就会很容易导致ora-100之类的错误。查看JDBC源码很容易理解。

#10


多谢hanjin26() ,难道只能通过Connection.close()来关闭所有的Statment和ResultSet了吗?
没有只是关闭所有的Statment和ResultSet而不需要关闭Connection的方法哈?
我前面已经说过,我的程序需要不停的操作数据库,是一个电信项目,所以connection要一直保持,不去关闭它,不然开销太大

#11


我想问下楼主,一直保持一连接相对连接用完就释放,那个系统的开销大?一直保持一个连接?1000个可以,10万呢,1000万呢?个人感觉思路有问题!

#12


不是不是,我这个程序没有那么多的数据库,就两个数据库,所以我的程序里只有两个连接,一个连接连一个数据库,没有你说的那么多的连接
只是这两个连接一直保持,不断进行数据处理,而且因为我主程序对每个数据库只进行一次连接,连接后进行数据处理,数据处理放在一个无线循环中,只是不停的执行SQL语句,不在进行数据库连接,所以整个进行一直保持的只有两个连接,哪有几千几万啊,进程异常退出才会关闭这两个连接的

#13


而且因为数据处理需要不停的处理数据,连接释放立即就需要连接,这样的话如果连接用完就释放,那么就需要在一个死循环不停的连接数据库,你觉得这个开销不大吗

#14


顶,希望还有高人可以指教

#15


rs用完就关,
         没有那种关所有rs和sm的方法.
           既然在循环里面就3,4句话都懒得写...

#16


不是3,4句,我的程序因为操作数据库比较多,得有10几句哈

而且有的时候还不好关闭,比如
                 rs3 = this.Conn1.executeSql(sql3);
try{
while(rs3.next()){
........
rs4 = this.Conn1.executeSql(sql4);

try{
while(rs4.next()){

.........
  }catch(){
  
  }
 }
 }catch(){ 
  
 }
请问上面这段怎么关闭statment和resultset?其中this.Conn1是和一个数据库的连接,对这个数据库嵌套做了操作,如果里层的while(rs4.next())关闭了statment和resultset,会不会影响外层的while(rs3.next())而使外层的循环不能在继续了

#17


自己顶

#18


建议自己实现一个Connection接口的类,然后里面封装一个Connection对象,然后自己实现一下CreateStatement方法,除了创建Statement外,把所有的Statement放在一个列表里面,增加一个关闭所有Statement方法,把列表里面的所有的Statement全部关闭掉。

#19


不过我觉得这种方法不是很好的方法,最好的方法就是在不用的时候就关闭掉,哪个方法打开的就要哪个方法关闭掉,保证各个方法之间松耦合,否则在一个稍微大一点的项目或者甚至是多线程的项目中,谁都无法预料会出现什么样的结果。

#20


既然return rs,返回了结果集,就不能在finally中把rs.close()掉,return之前会执行finally里的内容

rs用完就关,如果是嫌麻烦就自己写个函数一起关,如果是因为有循环嵌套不能关的,就封闭到集合中再循环

谁调用了executeSql方法就由谁关

#21


用连接池,apache 的,c3p0 的都不错。

你也可以试试这个是我些的
http://www.jspx.net/down/lib/jspxdbs-1.0.jar

    <bean id="jspxDataSource" class="com.jspx.datasource.JspxDataSource" destroy="close">
        <string name="driverClass">${driverClassName}</string>
        <string name="jdbcUrl"><![CDATA[${jdbcUrl}]]></string>
        <string name="user">${username}</string>
        <string name="password">${password}</string>
    </bean>

当你关闭的时候它不会关闭,当没有使用连接的时候会自动关闭连接。
setMaxPoolSize 设置最大连接数。
setMaxConnectionTime 最大连接等待时间,单位毫秒,超过这个时间就关闭。


#22


世纪书缘时隔两年多,《Java编程思想(第4版)》的中文版又要和广大Java程序员和爱好者们见面了。这是Java语言本身不断发展和完善的必然要求,也是本书作者Bruce Eckel孜孜不倦的创作激情和灵感所结出的硕果。

《Java编程思想(第4版)》以Java最新的版本JDK5.0为基础,在第3版的基础上,添加了最新的语言特性,并且对第3版的结构进行了调整,使得所有章节的安排更加遵照循序渐进的特点,同时每一章的内容在分量上也都更加均衡,这使读者能够更加容易地阅读本书并充分了解每章所讲述的内容。在这里我们再次向Bruce Eckel致敬,他不但向我们展示了什么样的书籍才是经典书籍,而且还展示了经典书籍怎样才能精益求精,长盛不衰。

Java已经成为了编程语言的骄子。我们可以看到,越来越多的大学在教授数据结构、程序设计和算法分析等课程时,选择以Java语言为载体。这说明Java语言已经是人们构建软件系统时主要使用的一种编程语言。但是,掌握好Java语言并不是一件可以轻松完成的任务,如何真正掌握Java语言,从而编写出健壮的、高效的以及灵活的程序是Java程序员们面临的重大挑战。

《Java编程思想(第4版)》就是一本能够让Java程序员轻松面对这一挑战,并最终取得胜利的经典书籍。本书深入浅出、循序渐进地把我们领入Java的世界,让我们在不知不觉中就学会了用Java的思想去考虑问题、解决问题。本书不仅适合Java的初学者,更适合于有经验的Java程序员,这正是本书的魅力所在。但是,书中并没有涵盖Java所有的类、接口和方法,因此,如果你希望将它当作Java的字典来使用,那么显然就要失望了。

我们在翻译本书的过程中力求忠于原著,为了保持连贯性,对原书第3版中仍然保持不变的部分,我们对译文除了个别地方之外,也没做修改。对于本书中出现的大量的专业术语尽量遵循标准的译法,并在有可能引起歧义之处注有英文原文,以方便读者对照与理解。

全书由陈昊鹏翻译,郭嘉也参与了部分翻译工作。由于水平有限,书中出现错误与不妥之处在所难免,恳请读者批评指正。www.sjsy.net

转载

#23


wang_wei2007() 

如果是因为有循环嵌套不能关的,就封闭到集合中再循环

什么意思?能具体说说吗?比如
 rs3 = this.Conn1.executeSql(sql3);
try{
while(rs3.next()){
........
rs4 = this.Conn1.executeSql(sql4);

try{
while(rs4.next()){

.........
  }catch(){
  
  }
 }
 }catch(){ 
  
 }
这样一段代码的关闭代码应该怎么写?

#24


疑问:
一个connection能带好多有效的resultset和statement吗?

我怎么觉得只能1拖1 的?

#25


to:jihanzhong(逍遥)

一个connection能带好多有效的resultset和statement吗?


应该可以,我程序里一个connection就带了好多resultset和statement,但是都能返回正确的结果

#26


其实我也一直在找楼主说的解决方案
并且想通过代理接口的方式实现
后来发现不妥,只好放弃了,
因为Connection生成的Statement和ResultSet始终不释放,
而是到最后才释放,可能会达到数据库联接的最大游标数而导致错误
例如:
try{
  rs1 = stmt.executeSql(sql1);
  while(rs1.next()){...}

  rs2 = stmt.executeSql(sql2);
  while(rs2.next()){...}
  ...

  rs100 = stmt.executeSql(sql4);
  while(rs100.next()){...}

 }catch(Exception){}
 finally{
    closeDBSourse(rs1);//1
    closeDBSourse(rs2);//2
    ...
    closeDBSourse(rs100);//100
    //1-100可能封装在函数101中

    freeDBSourse(stmt);//101
 }
可能在执行过程中会占用多个数据库游标,存在隐患。
目前我采用的实现方式如下,虽然比较繁琐,但很安全:
try{
  rs1 = stmt.executeSql(sql1);
  while(rs1.next()){...}
  closeDBSourse(rs1);

  rs2 = stmt.executeSql(sql2);
  while(rs2.next()){...}
  closeDBSourse(rs2);
  ...

  rs100 = stmt.executeSql(sql4);
  while(rs100.next()){...}
  closeDBSourse(rs100);

 }catch(Exception){}
 finally{
    freeDBSourse(stmt);
 }

#27


public ResultSet executeSql(String sqlstr){}

我认为像这样的设计就很不合理,至少返回的是一个封装后的数据(如:List),而不是直接返回一个 ResultSet,而且 finally 是先执行的(在其中关闭了 ResultSet),这个再返回就得不到结果集了。

这个方法应该改为:

public List<xxxx> executeSql(String sqlstr){}

这样就可以在里面直接关掉了。

#28


晕啊~~这个帖子是三个月前的!!

#29


还是在哪儿用到STATEMENT,RESULTSET就在哪儿关闭比较好吧

#30


这个方法应该改为:
public List<xxxx> executeSql(String sqlstr){}
=============================================
怎么实现这个方法呢?
ResultSet中返回的各字段属性不知道呀
是不是每个查询都要写一个这种方法,这可能要累死人

#31


其实我也一直在找楼主说的解决方案 
并且想通过代理接口的方式实现 
后来发现不妥,只好放弃了, 
因为Connection生成的Statement和ResultSet始终不释放, 
而是到最后才释放,可能会达到数据库联接的最大游标数而导致错误 
例如: 
try{ 
    rs1   =   stmt.executeSql(sql1); 
    while(rs1.next()){...} 

    rs2   =   stmt.executeSql(sql2); 
    while(rs2.next()){...} 
    ... 

    rs100   =   stmt.executeSql(sql4); 
    while(rs100.next()){...} 

  }catch(Exception){} 
  finally{ 
        closeDBSourse(rs1);//1 
        closeDBSourse(rs2);//2 
        ... 
        closeDBSourse(rs100);//100 
        //1-100可能封装在函数101中 

        freeDBSourse(stmt);//101 
  } 
可能在执行过程中会占用多个数据库游标,存在隐患。 
目前我采用的实现方式如下,虽然比较繁琐,但很安全: 
try{ 
    rs1   =   stmt.executeSql(sql1); 
    while(rs1.next()){...} 
    closeDBSourse(rs1); 

    rs2   =   stmt.executeSql(sql2); 
    while(rs2.next()){...} 
    closeDBSourse(rs2); 
    ... 

    rs100   =   stmt.executeSql(sql4); 
    while(rs100.next()){...} 
    closeDBSourse(rs100); 

  }catch(Exception){} 
  finally{ 
        freeDBSourse(stmt); 
  }

#32


直接返回ResultSet是不推荐的
应该根据自己的需求封装自己需要的数据类型,作为返回类型
这样就可以在返回之前关闭ResultSet

#33


别返回ResultSet,这样调用方和你这个方法的耦合程度就太高了

而且,你在你的方法里没法释放资源啊。

#1


在finally里关resultset和statement不可以?

#2


感觉你的代码结构有问题,尝试重构下

#3


页面上:
resultset.close();
 resultset=null;
 (statement) :opa
 opa.free();
在连接库的类里面:
// 进行数据库连接释放
public boolean free() {
try {
count--;

if (stmt != null) {
if (!stmt.getConnection().isClosed()) {
stmt.close();

}

}
if (connect != null) {
if (!connect.isClosed())
connect.close();
}
return true;
} catch (Exception e) {
return false;
}

}

#4


一种是通过项目组内部开发约束,约束你的开发人员用完statement、resultset之后必须在finally中关闭;

第二种方式是对操作数据库的方式都用Template Design Pattern封闭,类似Spring的JdbcTemplate那样,开发人员不用编写大量重复的关闭代码

第三种方式可以通过Adapter模式二次封装特定的JDBC包的Connection、Statement对象,实现Connection、Statement接口,分别让你的statement、resultset对象在Connection、Statement中可控制,比如Connection发放得一个Statement对象时,在你自定义的Connection类对象中可以保留一个这个对象的引用
, 之后可以通过调用方法connection.closeAllStatement(),遍历你所发放在外的Statement,对其发放在外的resultset对象关闭,之后再关闭自身,这样就能达到你所要的效果。也可以调用调用statement.closeAllResultset()对象来关闭这个statement发放在外的所有的resultset对象了。

#5


还是J2SE / 基础类的人比较好啊,这个问题刚开始发到J2SE / 扩展类好几天都没人回复,可能这个问题太简单?J2SE / 扩展类里的高人都不屑回答?

to gongyali2005(JAVA 民工)
你说的我试过,但是有问题
我之前发过这个问题,但是一直没有得到满意的答案,所以我就换了个问题,贴下之前的那个问题,其实现在这个问题就是因为要解决那个问题的
最近在做的一个程序,遇到了一个JDBC方面的问题,我的代码如下
 public  ResultSet  executeSql(String sqlstr)
  {
     Statement stmt = null;
     ResultSet  rs = null;

     try
     {
       stmt=conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
       rs=stmt.executeQuery(sqlstr);
       DebugLog.logger.log(Level.INFO,"获取数据集成功");
       return rs;
     }
     catch(SQLException e)
     {
       DebugLog.logger.log(Level.WARNING,"获取数据集时出现错误");
       DebugLog.logger.log(Level.WARNING,e.getMessage());
       try{
       conn.rollback();
       }
       catch(SQLException i)
   {
       DebugLog.logger.log(Level.WARNING,"回滚数据集时出现错误");
       DebugLog.logger.log(Level.WARNING,i.getMessage());
   }
       return null;
     }
     catch(Exception cnfe){
     DebugLog.logger.log(Level.WARNING,"获取数据集时出现错误");
     DebugLog.logger.log(Level.WARNING,cnfe.getMessage());
     return null;
     }  }
这是我之前写的一段JDBC操作数据库的代码,但是主程序运行一段时间出现这样的异常ora-01000: maximum open cursors exceeded.到网上查了下,说是已经达到一个进程打开的最大游标数,Java代码在执行conn.createStatement()和conn.prepareStatement()的时候,实际上都是相当与在数据库中打开了一个cursor。
尤其是,如果你的createStatement和prepareStatement是在一个循环里面的话,就会非常容易出现这个问题。因为游标一直在不停的打开,而且没有关闭,所以说,最好在执行了一次executeQuery、executeUpdate等之后,如果不需要使用结果集(ResultSet)的数据,就马上将Statment关闭。然后我的代码改进如下
 public  ResultSet  executeSql(String sqlstr)
  {
     Statement stmt = null;
     ResultSet  rs = null;

     try
     {
       stmt=conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
       rs=stmt.executeQuery(sqlstr);
       DebugLog.logger.log(Level.INFO,"获取数据集成功");
       return rs;
     }
     catch(SQLException e)
     {
       DebugLog.logger.log(Level.WARNING,"获取数据集时出现错误");
       DebugLog.logger.log(Level.WARNING,e.getMessage());
       try{
       conn.rollback();
       }
       catch(SQLException i)
   {
       DebugLog.logger.log(Level.WARNING,"回滚数据集时出现错误");
       DebugLog.logger.log(Level.WARNING,i.getMessage());
   }
       return null;
     }
     catch(Exception cnfe){
     DebugLog.logger.log(Level.WARNING,"获取数据集时出现错误");
     DebugLog.logger.log(Level.WARNING,cnfe.getMessage());
     return null;
     }finally{
     try{
     if(rs != null){
     rs.close();
     }
     if(stmt != null){
     stmt.close();
     }
     }catch(SQLException j){
     DebugLog.logger.log(Level.WARNING,"关闭数据集时出现错误");
     DebugLog.logger.log(Level.WARNING,j.getMessage());
     }     
     }
  }
但是这段代码的问题是,每次取这段代码执行SQL后返回的记录集,就会抛出一个信息为null的异常,我猜想是上面这个函数没返回任何记录集,rs是null的?
实在不知道什么原因,求高人指教,是什么原因?应该如何修改?谢谢了,我分不多,实在抱歉

#6


to zl8108304732() 我现在做的不是web程序哈,是在UNIX上后台运行的一个进程,现在做的项目是电信的一个新业务,这个进程需要在后台不停的处理数据,本来想用C来写的,因为我们公司之前的都是用C来实现,但是不知道怎么用C连接SQLSERVER,之前公司的都是连的oracle,所以改用java了,而且java操作数据库也比c简单的多,这个程序对性能也没太高的要求
不过还是谢谢你

to XinZi(新子),谢谢你哈,恩,你的第一种方式通过上面的代码看出,是不行的,因为要返回rs
现在这个新业务除了因为有些statement用完没有关闭,运行时间长了会出现ora-01000: maximum open cursors exceeded.,业务处理上已经测试没什么问题了,所以不想大改了,否则还得重新测试?电信的这个新业务马上就要推出去了
我试下你的第三种方式

#7


路过学习一下!

#8


有没有更好更简单的解决方法?比如connection的某个方法可以关闭该connection的所有创建的statement?

#9


调用Connection.close()关闭所有Statment和ResultSet,调用Statment.close()关闭所有ResultSet。
"resultset.close();"后面的“ resultset=null;”是多于的。"
Statment变量用完得关闭,特别是变量被多次赋值(stmt=conn.createStatement()),就会很容易导致ora-100之类的错误。查看JDBC源码很容易理解。

#10


多谢hanjin26() ,难道只能通过Connection.close()来关闭所有的Statment和ResultSet了吗?
没有只是关闭所有的Statment和ResultSet而不需要关闭Connection的方法哈?
我前面已经说过,我的程序需要不停的操作数据库,是一个电信项目,所以connection要一直保持,不去关闭它,不然开销太大

#11


我想问下楼主,一直保持一连接相对连接用完就释放,那个系统的开销大?一直保持一个连接?1000个可以,10万呢,1000万呢?个人感觉思路有问题!

#12


不是不是,我这个程序没有那么多的数据库,就两个数据库,所以我的程序里只有两个连接,一个连接连一个数据库,没有你说的那么多的连接
只是这两个连接一直保持,不断进行数据处理,而且因为我主程序对每个数据库只进行一次连接,连接后进行数据处理,数据处理放在一个无线循环中,只是不停的执行SQL语句,不在进行数据库连接,所以整个进行一直保持的只有两个连接,哪有几千几万啊,进程异常退出才会关闭这两个连接的

#13


而且因为数据处理需要不停的处理数据,连接释放立即就需要连接,这样的话如果连接用完就释放,那么就需要在一个死循环不停的连接数据库,你觉得这个开销不大吗

#14


顶,希望还有高人可以指教

#15


rs用完就关,
         没有那种关所有rs和sm的方法.
           既然在循环里面就3,4句话都懒得写...

#16


不是3,4句,我的程序因为操作数据库比较多,得有10几句哈

而且有的时候还不好关闭,比如
                 rs3 = this.Conn1.executeSql(sql3);
try{
while(rs3.next()){
........
rs4 = this.Conn1.executeSql(sql4);

try{
while(rs4.next()){

.........
  }catch(){
  
  }
 }
 }catch(){ 
  
 }
请问上面这段怎么关闭statment和resultset?其中this.Conn1是和一个数据库的连接,对这个数据库嵌套做了操作,如果里层的while(rs4.next())关闭了statment和resultset,会不会影响外层的while(rs3.next())而使外层的循环不能在继续了

#17


自己顶

#18


建议自己实现一个Connection接口的类,然后里面封装一个Connection对象,然后自己实现一下CreateStatement方法,除了创建Statement外,把所有的Statement放在一个列表里面,增加一个关闭所有Statement方法,把列表里面的所有的Statement全部关闭掉。

#19


不过我觉得这种方法不是很好的方法,最好的方法就是在不用的时候就关闭掉,哪个方法打开的就要哪个方法关闭掉,保证各个方法之间松耦合,否则在一个稍微大一点的项目或者甚至是多线程的项目中,谁都无法预料会出现什么样的结果。

#20


既然return rs,返回了结果集,就不能在finally中把rs.close()掉,return之前会执行finally里的内容

rs用完就关,如果是嫌麻烦就自己写个函数一起关,如果是因为有循环嵌套不能关的,就封闭到集合中再循环

谁调用了executeSql方法就由谁关

#21


用连接池,apache 的,c3p0 的都不错。

你也可以试试这个是我些的
http://www.jspx.net/down/lib/jspxdbs-1.0.jar

    <bean id="jspxDataSource" class="com.jspx.datasource.JspxDataSource" destroy="close">
        <string name="driverClass">${driverClassName}</string>
        <string name="jdbcUrl"><![CDATA[${jdbcUrl}]]></string>
        <string name="user">${username}</string>
        <string name="password">${password}</string>
    </bean>

当你关闭的时候它不会关闭,当没有使用连接的时候会自动关闭连接。
setMaxPoolSize 设置最大连接数。
setMaxConnectionTime 最大连接等待时间,单位毫秒,超过这个时间就关闭。


#22


世纪书缘时隔两年多,《Java编程思想(第4版)》的中文版又要和广大Java程序员和爱好者们见面了。这是Java语言本身不断发展和完善的必然要求,也是本书作者Bruce Eckel孜孜不倦的创作激情和灵感所结出的硕果。

《Java编程思想(第4版)》以Java最新的版本JDK5.0为基础,在第3版的基础上,添加了最新的语言特性,并且对第3版的结构进行了调整,使得所有章节的安排更加遵照循序渐进的特点,同时每一章的内容在分量上也都更加均衡,这使读者能够更加容易地阅读本书并充分了解每章所讲述的内容。在这里我们再次向Bruce Eckel致敬,他不但向我们展示了什么样的书籍才是经典书籍,而且还展示了经典书籍怎样才能精益求精,长盛不衰。

Java已经成为了编程语言的骄子。我们可以看到,越来越多的大学在教授数据结构、程序设计和算法分析等课程时,选择以Java语言为载体。这说明Java语言已经是人们构建软件系统时主要使用的一种编程语言。但是,掌握好Java语言并不是一件可以轻松完成的任务,如何真正掌握Java语言,从而编写出健壮的、高效的以及灵活的程序是Java程序员们面临的重大挑战。

《Java编程思想(第4版)》就是一本能够让Java程序员轻松面对这一挑战,并最终取得胜利的经典书籍。本书深入浅出、循序渐进地把我们领入Java的世界,让我们在不知不觉中就学会了用Java的思想去考虑问题、解决问题。本书不仅适合Java的初学者,更适合于有经验的Java程序员,这正是本书的魅力所在。但是,书中并没有涵盖Java所有的类、接口和方法,因此,如果你希望将它当作Java的字典来使用,那么显然就要失望了。

我们在翻译本书的过程中力求忠于原著,为了保持连贯性,对原书第3版中仍然保持不变的部分,我们对译文除了个别地方之外,也没做修改。对于本书中出现的大量的专业术语尽量遵循标准的译法,并在有可能引起歧义之处注有英文原文,以方便读者对照与理解。

全书由陈昊鹏翻译,郭嘉也参与了部分翻译工作。由于水平有限,书中出现错误与不妥之处在所难免,恳请读者批评指正。www.sjsy.net

转载

#23


wang_wei2007() 

如果是因为有循环嵌套不能关的,就封闭到集合中再循环

什么意思?能具体说说吗?比如
 rs3 = this.Conn1.executeSql(sql3);
try{
while(rs3.next()){
........
rs4 = this.Conn1.executeSql(sql4);

try{
while(rs4.next()){

.........
  }catch(){
  
  }
 }
 }catch(){ 
  
 }
这样一段代码的关闭代码应该怎么写?

#24


疑问:
一个connection能带好多有效的resultset和statement吗?

我怎么觉得只能1拖1 的?

#25


to:jihanzhong(逍遥)

一个connection能带好多有效的resultset和statement吗?


应该可以,我程序里一个connection就带了好多resultset和statement,但是都能返回正确的结果

#26


其实我也一直在找楼主说的解决方案
并且想通过代理接口的方式实现
后来发现不妥,只好放弃了,
因为Connection生成的Statement和ResultSet始终不释放,
而是到最后才释放,可能会达到数据库联接的最大游标数而导致错误
例如:
try{
  rs1 = stmt.executeSql(sql1);
  while(rs1.next()){...}

  rs2 = stmt.executeSql(sql2);
  while(rs2.next()){...}
  ...

  rs100 = stmt.executeSql(sql4);
  while(rs100.next()){...}

 }catch(Exception){}
 finally{
    closeDBSourse(rs1);//1
    closeDBSourse(rs2);//2
    ...
    closeDBSourse(rs100);//100
    //1-100可能封装在函数101中

    freeDBSourse(stmt);//101
 }
可能在执行过程中会占用多个数据库游标,存在隐患。
目前我采用的实现方式如下,虽然比较繁琐,但很安全:
try{
  rs1 = stmt.executeSql(sql1);
  while(rs1.next()){...}
  closeDBSourse(rs1);

  rs2 = stmt.executeSql(sql2);
  while(rs2.next()){...}
  closeDBSourse(rs2);
  ...

  rs100 = stmt.executeSql(sql4);
  while(rs100.next()){...}
  closeDBSourse(rs100);

 }catch(Exception){}
 finally{
    freeDBSourse(stmt);
 }

#27


public ResultSet executeSql(String sqlstr){}

我认为像这样的设计就很不合理,至少返回的是一个封装后的数据(如:List),而不是直接返回一个 ResultSet,而且 finally 是先执行的(在其中关闭了 ResultSet),这个再返回就得不到结果集了。

这个方法应该改为:

public List<xxxx> executeSql(String sqlstr){}

这样就可以在里面直接关掉了。

#28


晕啊~~这个帖子是三个月前的!!

#29


还是在哪儿用到STATEMENT,RESULTSET就在哪儿关闭比较好吧

#30


这个方法应该改为:
public List<xxxx> executeSql(String sqlstr){}
=============================================
怎么实现这个方法呢?
ResultSet中返回的各字段属性不知道呀
是不是每个查询都要写一个这种方法,这可能要累死人

#31


其实我也一直在找楼主说的解决方案 
并且想通过代理接口的方式实现 
后来发现不妥,只好放弃了, 
因为Connection生成的Statement和ResultSet始终不释放, 
而是到最后才释放,可能会达到数据库联接的最大游标数而导致错误 
例如: 
try{ 
    rs1   =   stmt.executeSql(sql1); 
    while(rs1.next()){...} 

    rs2   =   stmt.executeSql(sql2); 
    while(rs2.next()){...} 
    ... 

    rs100   =   stmt.executeSql(sql4); 
    while(rs100.next()){...} 

  }catch(Exception){} 
  finally{ 
        closeDBSourse(rs1);//1 
        closeDBSourse(rs2);//2 
        ... 
        closeDBSourse(rs100);//100 
        //1-100可能封装在函数101中 

        freeDBSourse(stmt);//101 
  } 
可能在执行过程中会占用多个数据库游标,存在隐患。 
目前我采用的实现方式如下,虽然比较繁琐,但很安全: 
try{ 
    rs1   =   stmt.executeSql(sql1); 
    while(rs1.next()){...} 
    closeDBSourse(rs1); 

    rs2   =   stmt.executeSql(sql2); 
    while(rs2.next()){...} 
    closeDBSourse(rs2); 
    ... 

    rs100   =   stmt.executeSql(sql4); 
    while(rs100.next()){...} 
    closeDBSourse(rs100); 

  }catch(Exception){} 
  finally{ 
        freeDBSourse(stmt); 
  }

#32


直接返回ResultSet是不推荐的
应该根据自己的需求封装自己需要的数据类型,作为返回类型
这样就可以在返回之前关闭ResultSet

#33


别返回ResultSet,这样调用方和你这个方法的耦合程度就太高了

而且,你在你的方法里没法释放资源啊。