我程序中有以下连续的三种sql 
-------------------------------------------------- 
stmt = dbConn.prepareStatement(select_sql); 
...set参数 
rs=stmt.executeQuery(); -------------------------------------------------- 
stmt = dbConn.prepareStatement(update_sql); 
...set参数 
execute(); 
-------------------------------------------------- 
stmt = dbConn.prepareStatement(insert_sql); 
...set参数 
execute(); 在程序中我只申明了一个stmt,在执行下一个sql之前,我是否应该先stmt.close()一下呢,这样将出现3个close动作 
还是只需要在最后执行一次stmt.close()就可用了呢 ??? 这里虽然对stmt进行了三次赋值,但它一直持有的都是 
同一个句柄吧 ? 

解决方案 »

  1.   

    下面的代码是反编译得到的mysql的jdbc5.1.6的jar包中的PreparedStatement的实现中的close方法.    public synchronized void close()
            throws SQLException
        {
            realClose(true, true);
        }
    close调用了下面这个方法    protected void realClose(boolean calledExplicitly, boolean closeOpenResults)
            throws SQLException
        {
            if(useUsageAdvisor && numberOfExecutions <= 1)
            {
                String message = Messages.getString("PreparedStatement.43");
                eventSink.consumeEvent(new ProfilerEvent((byte)0, "", currentCatalog, connectionId, getId(), -1, System.currentTimeMillis(), 0L, Constants.MILLIS_I18N, null, pointOfOrigin, message));
            }
            super.realClose(calledExplicitly, closeOpenResults); 
    //上面一句调用了父类的realClose()方法, 父类StatementImpl的这个方法代码在下面..
    //下面这些地方做了很多成员的释放...
            dbmd = null;
            originalSql = null;
            staticSqlStrings = (byte[][])null;
            parameterValues = (byte[][])null;
            parameterStreams = null;
            isStream = null;
            streamLengths = null;
            isNull = null;
            streamConvertBuf = null;
            parameterTypes = null;
        }
    下面这就是父类StatementImpl中的realClose方法    protected void realClose(boolean calledExplicitly, boolean closeOpenResults)
            throws SQLException
        {
            if(isClosed)
                return;
            if(useUsageAdvisor && !calledExplicitly)
            {
                String message = Messages.getString("Statement.63") + Messages.getString("Statement.64");
                eventSink.consumeEvent(new ProfilerEvent((byte)0, "", currentCatalog, connectionId, getId(), -1, System.currentTimeMillis(), 0L, Constants.MILLIS_I18N, null, pointOfOrigin, message));
            }
            if(closeOpenResults)
                closeOpenResults = !holdResultsOpenOverClose;
            if(closeOpenResults)
            {
                if(results != null)
                    try
                    {
                        results.close();
                    }
                    catch(Exception ex) { }
                closeAllOpenResults();
            }
            if(connection != null)
            {
                if(maxRowsChanged)
                    connection.unsetMaxRows(this);
                if(!connection.getDontTrackOpenResources())
                    connection.unregisterStatement(this);
            }
    //同样,下面有很多的释放语句
            isClosed = true;
            results = null;
            connection = null;
            warningChain = null;
            openResults = null;
            batchedGeneratedKeys = null;
            localInfileInputStream = null;
            pingTarget = null;
        }
      

  2.   

    用一个,后面就要close一个。