我知道直接关闭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;
}
}
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对象了。
第二种方式是对操作数据库的方式都用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的?
实在不知道什么原因,求高人指教,是什么原因?应该如何修改?谢谢了,我分不多,实在抱歉
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.,业务处理上已经测试没什么问题了,所以不想大改了,否则还得重新测试?电信的这个新业务马上就要推出去了
我试下你的第三种方式
不过还是谢谢你
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源码很容易理解。
"resultset.close();"后面的“ resultset=null;”是多于的。"
Statment变量用完得关闭,特别是变量被多次赋值(stmt=conn.createStatement()),就会很容易导致ora-100之类的错误。查看JDBC源码很容易理解。
#10
多谢hanjin26() ,难道只能通过Connection.close()来关闭所有的Statment和ResultSet了吗?
没有只是关闭所有的Statment和ResultSet而不需要关闭Connection的方法哈?
我前面已经说过,我的程序需要不停的操作数据库,是一个电信项目,所以connection要一直保持,不去关闭它,不然开销太大
没有只是关闭所有的Statment和ResultSet而不需要关闭Connection的方法哈?
我前面已经说过,我的程序需要不停的操作数据库,是一个电信项目,所以connection要一直保持,不去关闭它,不然开销太大
#11
我想问下楼主,一直保持一连接相对连接用完就释放,那个系统的开销大?一直保持一个连接?1000个可以,10万呢,1000万呢?个人感觉思路有问题!
#12
不是不是,我这个程序没有那么多的数据库,就两个数据库,所以我的程序里只有两个连接,一个连接连一个数据库,没有你说的那么多的连接
只是这两个连接一直保持,不断进行数据处理,而且因为我主程序对每个数据库只进行一次连接,连接后进行数据处理,数据处理放在一个无线循环中,只是不停的执行SQL语句,不在进行数据库连接,所以整个进行一直保持的只有两个连接,哪有几千几万啊,进程异常退出才会关闭这两个连接的
只是这两个连接一直保持,不断进行数据处理,而且因为我主程序对每个数据库只进行一次连接,连接后进行数据处理,数据处理放在一个无线循环中,只是不停的执行SQL语句,不在进行数据库连接,所以整个进行一直保持的只有两个连接,哪有几千几万啊,进程异常退出才会关闭这两个连接的
#13
而且因为数据处理需要不停的处理数据,连接释放立即就需要连接,这样的话如果连接用完就释放,那么就需要在一个死循环不停的连接数据库,你觉得这个开销不大吗
#14
顶,希望还有高人可以指教
#15
rs用完就关,
没有那种关所有rs和sm的方法.
既然在循环里面就3,4句话都懒得写...
没有那种关所有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())而使外层的循环不能在继续了
而且有的时候还不好关闭,比如
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方法就由谁关
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 最大连接等待时间,单位毫秒,超过这个时间就关闭。
你也可以试试这个是我些的
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
转载
《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(){
}
这样一段代码的关闭代码应该怎么写?
如果是因为有循环嵌套不能关的,就封闭到集合中再循环
什么意思?能具体说说吗?比如
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 的?
一个connection能带好多有效的resultset和statement吗?
我怎么觉得只能1拖1 的?
#25
to:jihanzhong(逍遥)
一个connection能带好多有效的resultset和statement吗?
应该可以,我程序里一个connection就带了好多resultset和statement,但是都能返回正确的结果
一个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);
}
并且想通过代理接口的方式实现
后来发现不妥,只好放弃了,
因为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){}
这样就可以在里面直接关掉了。
我认为像这样的设计就很不合理,至少返回的是一个封装后的数据(如:List),而不是直接返回一个 ResultSet,而且 finally 是先执行的(在其中关闭了 ResultSet),这个再返回就得不到结果集了。
这个方法应该改为:
public List<xxxx> executeSql(String sqlstr){}
这样就可以在里面直接关掉了。
#28
晕啊~~这个帖子是三个月前的!!
#29
还是在哪儿用到STATEMENT,RESULTSET就在哪儿关闭比较好吧
#30
这个方法应该改为:
public List<xxxx> executeSql(String sqlstr){}
=============================================
怎么实现这个方法呢?
ResultSet中返回的各字段属性不知道呀
是不是每个查询都要写一个这种方法,这可能要累死人
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);
}
并且想通过代理接口的方式实现
后来发现不妥,只好放弃了,
因为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
应该根据自己的需求封装自己需要的数据类型,作为返回类型
这样就可以在返回之前关闭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;
}
}
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对象了。
第二种方式是对操作数据库的方式都用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的?
实在不知道什么原因,求高人指教,是什么原因?应该如何修改?谢谢了,我分不多,实在抱歉
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.,业务处理上已经测试没什么问题了,所以不想大改了,否则还得重新测试?电信的这个新业务马上就要推出去了
我试下你的第三种方式
不过还是谢谢你
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源码很容易理解。
"resultset.close();"后面的“ resultset=null;”是多于的。"
Statment变量用完得关闭,特别是变量被多次赋值(stmt=conn.createStatement()),就会很容易导致ora-100之类的错误。查看JDBC源码很容易理解。
#10
多谢hanjin26() ,难道只能通过Connection.close()来关闭所有的Statment和ResultSet了吗?
没有只是关闭所有的Statment和ResultSet而不需要关闭Connection的方法哈?
我前面已经说过,我的程序需要不停的操作数据库,是一个电信项目,所以connection要一直保持,不去关闭它,不然开销太大
没有只是关闭所有的Statment和ResultSet而不需要关闭Connection的方法哈?
我前面已经说过,我的程序需要不停的操作数据库,是一个电信项目,所以connection要一直保持,不去关闭它,不然开销太大
#11
我想问下楼主,一直保持一连接相对连接用完就释放,那个系统的开销大?一直保持一个连接?1000个可以,10万呢,1000万呢?个人感觉思路有问题!
#12
不是不是,我这个程序没有那么多的数据库,就两个数据库,所以我的程序里只有两个连接,一个连接连一个数据库,没有你说的那么多的连接
只是这两个连接一直保持,不断进行数据处理,而且因为我主程序对每个数据库只进行一次连接,连接后进行数据处理,数据处理放在一个无线循环中,只是不停的执行SQL语句,不在进行数据库连接,所以整个进行一直保持的只有两个连接,哪有几千几万啊,进程异常退出才会关闭这两个连接的
只是这两个连接一直保持,不断进行数据处理,而且因为我主程序对每个数据库只进行一次连接,连接后进行数据处理,数据处理放在一个无线循环中,只是不停的执行SQL语句,不在进行数据库连接,所以整个进行一直保持的只有两个连接,哪有几千几万啊,进程异常退出才会关闭这两个连接的
#13
而且因为数据处理需要不停的处理数据,连接释放立即就需要连接,这样的话如果连接用完就释放,那么就需要在一个死循环不停的连接数据库,你觉得这个开销不大吗
#14
顶,希望还有高人可以指教
#15
rs用完就关,
没有那种关所有rs和sm的方法.
既然在循环里面就3,4句话都懒得写...
没有那种关所有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())而使外层的循环不能在继续了
而且有的时候还不好关闭,比如
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方法就由谁关
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 最大连接等待时间,单位毫秒,超过这个时间就关闭。
你也可以试试这个是我些的
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
转载
《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(){
}
这样一段代码的关闭代码应该怎么写?
如果是因为有循环嵌套不能关的,就封闭到集合中再循环
什么意思?能具体说说吗?比如
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 的?
一个connection能带好多有效的resultset和statement吗?
我怎么觉得只能1拖1 的?
#25
to:jihanzhong(逍遥)
一个connection能带好多有效的resultset和statement吗?
应该可以,我程序里一个connection就带了好多resultset和statement,但是都能返回正确的结果
一个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);
}
并且想通过代理接口的方式实现
后来发现不妥,只好放弃了,
因为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){}
这样就可以在里面直接关掉了。
我认为像这样的设计就很不合理,至少返回的是一个封装后的数据(如:List),而不是直接返回一个 ResultSet,而且 finally 是先执行的(在其中关闭了 ResultSet),这个再返回就得不到结果集了。
这个方法应该改为:
public List<xxxx> executeSql(String sqlstr){}
这样就可以在里面直接关掉了。
#28
晕啊~~这个帖子是三个月前的!!
#29
还是在哪儿用到STATEMENT,RESULTSET就在哪儿关闭比较好吧
#30
这个方法应该改为:
public List<xxxx> executeSql(String sqlstr){}
=============================================
怎么实现这个方法呢?
ResultSet中返回的各字段属性不知道呀
是不是每个查询都要写一个这种方法,这可能要累死人
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);
}
并且想通过代理接口的方式实现
后来发现不妥,只好放弃了,
因为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
应该根据自己的需求封装自己需要的数据类型,作为返回类型
这样就可以在返回之前关闭ResultSet
#33
别返回ResultSet,这样调用方和你这个方法的耦合程度就太高了
而且,你在你的方法里没法释放资源啊。
而且,你在你的方法里没法释放资源啊。