📄 statement.java
字号:
} /** * In many cases, it is desirable to immediately release a Statement's * database and JDBC resources instead of waiting for this to happen when it * is automatically closed. The close method provides this immediate * release. * * <p> * <B>Note:</B> A Statement is automatically closed when it is garbage * collected. When a Statement is closed, its current ResultSet, if one * exists, is also closed. * </p> * * @exception SQLException * if a database access error occurs */ public void close() throws SQLException { realClose(true, true); } /** * Close any open result sets that have been 'held open' */ protected void closeAllOpenResults() { if (this.openResults != null) { for (Iterator iter = this.openResults.iterator(); iter.hasNext();) { ResultSet element = (ResultSet) iter.next(); try { element.realClose(false); } catch (SQLException sqlEx) { AssertionFailedException.shouldNotHappen(sqlEx); } } this.openResults.clear(); } } /** * @param sql * @return */ private ResultSet createResultSetUsingServerFetch(String sql) throws SQLException { java.sql.PreparedStatement pStmt = this.connection.prepareStatement( sql, this.resultSetType, this.resultSetConcurrency); pStmt.setFetchSize(this.fetchSize); if (this.maxRows > -1) { pStmt.setMaxRows(this.maxRows); } pStmt.execute(); // // Need to be able to get resultset irrespective if we issued DML or // not to make this work. // ResultSet rs = ((com.mysql.jdbc.Statement) pStmt) .getResultSetInternal(); rs .setStatementUsedForFetchingRows((com.mysql.jdbc.PreparedStatement) pStmt); this.results = rs; return rs; } /** * We only stream result sets when they are forward-only, read-only, and the * fetch size has been set to Integer.MIN_VALUE * * @return true if this result set should be streamed row at-a-time, rather * than read all at once. */ protected boolean createStreamingResultSet() { return ((this.resultSetType == java.sql.ResultSet.TYPE_FORWARD_ONLY) && (this.resultSetConcurrency == java.sql.ResultSet.CONCUR_READ_ONLY) && (this.fetchSize == Integer.MIN_VALUE)); } /** * Workaround for containers that 'check' for sane values of * Statement.setFetchSize(). * * @throws SQLException */ public void enableStreamingResults() throws SQLException { setFetchSize(Integer.MIN_VALUE); setResultSetType(ResultSet.TYPE_FORWARD_ONLY); } /** * Execute a SQL statement that may return multiple results. We don't have * to worry about this since we do not support multiple ResultSets. You can * use getResultSet or getUpdateCount to retrieve the result. * * @param sql * any SQL statement * * @return true if the next result is a ResulSet, false if it is an update * count or there are no more results * * @exception SQLException * if a database access error occurs */ public boolean execute(String sql) throws SQLException { checkClosed(); Connection locallyScopedConn = this.connection; synchronized (locallyScopedConn.getMutex()) { synchronized (this.cancelTimeoutMutex) { this.wasCancelled = false; } checkNullOrEmptyQuery(sql); checkClosed(); char firstNonWsChar = StringUtils.firstNonWsCharUc(sql); boolean isSelect = true; if (firstNonWsChar != 'S') { isSelect = false; if (locallyScopedConn.isReadOnly()) { throw SQLError.createSQLException(Messages .getString("Statement.27") //$NON-NLS-1$ + Messages.getString("Statement.28"), //$NON-NLS-1$ SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ } } if (this.doEscapeProcessing) { Object escapedSqlResult = EscapeProcessor.escapeSQL(sql, locallyScopedConn.serverSupportsConvertFn(), locallyScopedConn); if (escapedSqlResult instanceof String) { sql = (String) escapedSqlResult; } else { sql = ((EscapeProcessorResult) escapedSqlResult).escapedSql; } } if (this.results != null) { if (!locallyScopedConn.getHoldResultsOpenOverStatementClose()) { this.results.realClose(false); } } CachedResultSetMetaData cachedMetaData = null; ResultSet rs = null; // If there isn't a limit clause in the SQL // then limit the number of rows to return in // an efficient manner. Only do this if // setMaxRows() hasn't been used on any Statements // generated from the current Connection (saves // a query, and network traffic). this.batchedGeneratedKeys = null; if (useServerFetch()) { rs = createResultSetUsingServerFetch(sql); } else { CancelTask timeoutTask = null; String oldCatalog = null; try { if (locallyScopedConn.getEnableQueryTimeouts() && this.timeoutInMillis != 0 && locallyScopedConn.versionMeetsMinimum(5, 0, 0)) { timeoutTask = new CancelTask(); Connection.getCancelTimer().schedule(timeoutTask, this.timeoutInMillis); } if (!locallyScopedConn.getCatalog().equals( this.currentCatalog)) { oldCatalog = locallyScopedConn.getCatalog(); locallyScopedConn.setCatalog(this.currentCatalog); } // // Check if we have cached metadata for this query... // if (locallyScopedConn.getCacheResultSetMetadata()) { cachedMetaData = locallyScopedConn.getCachedMetaData(sql); } // // Only apply max_rows to selects // if (locallyScopedConn.useMaxRows()) { int rowLimit = -1; if (isSelect) { if (StringUtils.indexOfIgnoreCase(sql, "LIMIT") != -1) { //$NON-NLS-1$ rowLimit = this.maxRows; } else { if (this.maxRows <= 0) { locallyScopedConn .execSQL( this, "SET OPTION SQL_SELECT_LIMIT=DEFAULT", -1, //$NON-NLS-1$ null, java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY, false, this.currentCatalog, true); //$NON-NLS-1$ } else { locallyScopedConn .execSQL( this, "SET OPTION SQL_SELECT_LIMIT=" + this.maxRows, //$NON-NLS-1$ -1, null, java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY, false, this.currentCatalog, true); //$NON-NLS-1$ } } } else { locallyScopedConn .execSQL( this, "SET OPTION SQL_SELECT_LIMIT=DEFAULT", -1, null, //$NON-NLS-1$ java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY, false, this.currentCatalog, true); //$NON-NLS-1$ } // Finally, execute the query rs = locallyScopedConn.execSQL(this, sql, rowLimit, null, this.resultSetType, this.resultSetConcurrency, createStreamingResultSet(), this.currentCatalog, (cachedMetaData == null)); } else { rs = locallyScopedConn.execSQL(this, sql, -1, null, this.resultSetType, this.resultSetConcurrency, createStreamingResultSet(), this.currentCatalog, (cachedMetaData == null)); } if (timeoutTask != null) { if (timeoutTask.caughtWhileCancelling != null) { throw timeoutTask.caughtWhileCancelling; } timeoutTask.cancel(); timeoutTask = null; } synchronized (this.cancelTimeoutMutex) { if (this.wasCancelled) { this.wasCancelled = false; throw new MySQLTimeoutException(); } } } finally { if (timeoutTask != null) { timeoutTask.cancel(); } if (oldCatalog != null) { locallyScopedConn.setCatalog(oldCatalog); } } } this.lastInsertId = rs.getUpdateID(); if (rs != null) { this.results = rs; rs.setFirstCharOfQuery(firstNonWsChar); if (rs.reallyResult()) { if (cachedMetaData != null) { locallyScopedConn.initializeResultsMetadataFromCache(sql, cachedMetaData, this.results); } else { if (this.connection.getCacheResultSetMetadata()) { locallyScopedConn.initializeResultsMetadataFromCache(sql, null /* will be created */, this.results); } } } } return ((rs != null) && rs.reallyResult()); } } /** * @see Statement#execute(String, int) */ public boolean execute(String sql, int returnGeneratedKeys) throws SQLException { if (returnGeneratedKeys == java.sql.Statement.RETURN_GENERATED_KEYS) { checkClosed(); Connection locallyScopedConn = this.connection; synchronized (locallyScopedConn.getMutex()) { // If this is a 'REPLACE' query, we need to be able to parse // the 'info' message returned from the server to determine // the actual number of keys generated. boolean readInfoMsgState = this.connection .isReadInfoMsgEnabled(); locallyScopedConn.setReadInfoMsgEnabled(true); try { return execute(sql); } finally { locallyScopedConn.setReadInfoMsgEnabled(readInfoMsgState); } } } return execute(sql); } /** * @see Statement#execute(String, int[]) */ public boolean execute(String sql, int[] generatedKeyIndices) throws SQLException { if ((generatedKeyIndices != null) && (generatedKeyIndices.length > 0)) { checkClosed(); Connection locallyScopedConn = this.connection; synchronized (locallyScopedConn.getMutex()) { // If this is a 'REPLACE' query, we need to be able to parse // the 'info' message returned from the server to determine // the actual number of keys generated. boolean readInfoMsgState = locallyScopedConn .isReadInfoMsgEnabled(); locallyScopedConn.setReadInfoMsgEnabled(true); try { return execute(sql); } finally { locallyScopedConn.setReadInfoMsgEnabled(readInfoMsgState); } } } return execute(sql); } /** * @see Statement#execute(String, String[]) */ public boolean execute(String sql, String[] generatedKeyNames) throws SQLException { if ((generatedKeyNames != null) && (generatedKeyNames.length > 0)) { checkClosed(); Connection locallyScopedConn = this.connection; synchronized (locallyScopedConn.getMutex()) { // If this is a 'REPLACE' query, we need to be able to parse // the 'info' message returned from the server to determine // the actual number of keys generated. boolean readInfoMsgState = this.connection .isReadInfoMsgEnabled(); locallyScopedConn.setReadInfoMsgEnabled(true); try { return execute(sql); } finally { locallyScopedConn.setReadInfoMsgEnabled(readInfoMsgState); } } } return execute(sql); } /** * JDBC 2.0 Submit a batch of commands to the database for execution. This * method is optional. * * @return an array of update counts containing one element for each command * in the batch. The array is ordered according to the order in * which commands were inserted into the batch * * @exception SQLException * if a database-access error occurs, or the driver does not * support batch statements * @throws java.sql.BatchUpdateException * DOCUMENT ME! */ public synchronized int[] executeBatch() throws SQLException { checkClosed(); Connection locallyScopedConn = this.connection; if (locallyScopedConn.isReadOnly()) { throw SQLError.createSQLException(Messages .getString("Statement.34") //$NON-NLS-1$ + Messages.getString("Statement.35"), //$NON-NLS-1$ SQLError.SQL_STATE_ILLEGAL_ARGUMENT); //$NON-NLS-1$ } if (this.results != null) { if (!locallyScopedConn.getHoldResultsOpenOverStatementClose()) { this.results.realClose(false); } } synchronized (locallyScopedConn.getMutex()) { try { this.retrieveGeneratedKeys = true; int[] updateCounts = null; if (this.batchedArgs != null) { int nbrCommands = this.batchedArgs.size(); this.batchedGeneratedKeys = new ArrayList(this.batchedArgs.size()); boolean multiQueriesEnabled = locallyScopedConn.getAllowMultiQueries(); if (locallyScopedConn.versionMeetsMinimum(4, 1, 1) && (multiQueriesEnabled || (locallyScopedConn.getRewriteBatchedStatements() && nbrCommands > 4))) { return executeBatchUsingMultiQueries(multiQueriesEnabled, nbrCommands); } updateCounts = new int[nbrCommands]; for (int i = 0; i < nbrCommands; i++) { updateCounts[i] = -3; } SQLException sqlEx = null; int commandIndex = 0; for (commandIndex = 0; commandIndex < nbrCommands; commandIndex++) { try { updateCounts[commandIndex] = executeUpdate((String) this.batchedArgs .get(commandIndex), true); getBatchedGeneratedKeys(); } catch (SQLException ex) { updateCounts[commandIndex] = EXECUTE_FAILED;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -