?? preparedstatement.java
字號:
String oldCatalog = null; 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(this.originalSql); } Field[] metadataFromCache = null; if (cachedMetadata != null) { metadataFromCache = cachedMetadata.fields; } boolean oldInfoMsgState = false; if (this.retrieveGeneratedKeys) { oldInfoMsgState = locallyScopedConn.isReadInfoMsgEnabled(); locallyScopedConn.setReadInfoMsgEnabled(true); } // 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). // // Only apply max_rows to selects // if (locallyScopedConn.useMaxRows()) { int rowLimit = -1; if (this.firstCharOfStmt == 'S') { if (this.hasLimitClause) { rowLimit = this.maxRows; } else { if (this.maxRows <= 0) { executeSimpleNonQuery(locallyScopedConn, "SET OPTION SQL_SELECT_LIMIT=DEFAULT"); } else { executeSimpleNonQuery(locallyScopedConn, "SET OPTION SQL_SELECT_LIMIT=" + this.maxRows); } } } else { executeSimpleNonQuery(locallyScopedConn, "SET OPTION SQL_SELECT_LIMIT=DEFAULT"); } // Finally, execute the query rs = executeInternal(rowLimit, sendPacket, doStreaming, (this.firstCharOfStmt == 'S'), metadataFromCache, false); } else { rs = executeInternal(-1, sendPacket, doStreaming, (this.firstCharOfStmt == 'S'), metadataFromCache, false); } if (cachedMetadata != null) { locallyScopedConn.initializeResultsMetadataFromCache(this.originalSql, cachedMetadata, this.results); } else { if (rs.reallyResult() && locallyScopedConn.getCacheResultSetMetadata()) { locallyScopedConn.initializeResultsMetadataFromCache(this.originalSql, null /* will be created */, rs); } } if (this.retrieveGeneratedKeys) { locallyScopedConn.setReadInfoMsgEnabled(oldInfoMsgState); rs.setFirstCharOfQuery(this.firstCharOfStmt); } if (oldCatalog != null) { locallyScopedConn.setCatalog(oldCatalog); } if (rs != null) { this.lastInsertId = rs.getUpdateID(); this.results = rs; } } return ((rs != null) && rs.reallyResult()); } /** * 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 int[] executeBatch() throws SQLException { checkClosed(); if (this.connection.isReadOnly()) { throw new SQLException(Messages.getString("PreparedStatement.25") //$NON-NLS-1$ + Messages.getString("PreparedStatement.26"), //$NON-NLS-1$ SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } synchronized (this.connection.getMutex()) { if (this.batchedArgs == null || this.batchedArgs.size() == 0) { return new int[0]; } // we timeout the entire batch, not individual statements int batchTimeout = this.timeoutInMillis; this.timeoutInMillis = 0; resetCancelledState(); try { clearWarnings(); if (!this.batchHasPlainStatements && this.connection.getRewriteBatchedStatements()) { if (canRewriteAsMultivalueInsertStatement()) { return executeBatchedInserts(batchTimeout); } if (this.connection.versionMeetsMinimum(4, 1, 0) && !this.batchHasPlainStatements && this.batchedArgs != null && this.batchedArgs.size() > 3 /* cost of option setting rt-wise */) { return executePreparedBatchAsMultiStatement(batchTimeout); } } return executeBatchSerially(batchTimeout); } finally { clearBatch(); } } } public synchronized boolean canRewriteAsMultivalueInsertStatement() { if (!this.hasCheckedForRewrite) { // Needs to be INSERT, can't have INSERT ... SELECT or // INSERT ... ON DUPLICATE KEY UPDATE // // We're not smart enough to re-write to // // INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6) // ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b); // // (yet) this.canRewrite = StringUtils.startsWithIgnoreCaseAndWs( this.originalSql, "INSERT", this.statementAfterCommentsPos) && StringUtils.indexOfIgnoreCaseRespectMarker(this.statementAfterCommentsPos, this.originalSql, "SELECT", "\"'`", "\"'`", false) == -1 && StringUtils.indexOfIgnoreCaseRespectMarker(this.statementAfterCommentsPos, this.originalSql, "UPDATE", "\"'`", "\"'`", false) == -1; this.hasCheckedForRewrite = true; } return this.canRewrite; } /** * Rewrites the already prepared statement into a multi-statement * query of 'statementsPerBatch' values and executes the entire batch * using this new statement. * * @return update counts in the same fashion as executeBatch() * * @throws SQLException */ protected int[] executePreparedBatchAsMultiStatement(int batchTimeout) throws SQLException { synchronized (this.connection.getMutex()) { // This is kind of an abuse, but it gets the job done if (this.batchedValuesClause == null) { this.batchedValuesClause = this.originalSql + ";"; } ConnectionImpl locallyScopedConn = this.connection; boolean multiQueriesEnabled = locallyScopedConn.getAllowMultiQueries(); CancelTask timeoutTask = null; try { clearWarnings(); int numBatchedArgs = this.batchedArgs.size(); if (this.retrieveGeneratedKeys) { this.batchedGeneratedKeys = new ArrayList(numBatchedArgs); } int numValuesPerBatch = computeBatchSize(numBatchedArgs); if (numBatchedArgs < numValuesPerBatch) { numValuesPerBatch = numBatchedArgs; } java.sql.PreparedStatement batchedStatement = null; int batchedParamIndex = 1; int numberToExecuteAsMultiValue = 0; int batchCounter = 0; int updateCountCounter = 0; int[] updateCounts = new int[numBatchedArgs]; SQLException sqlEx = null; try { if (!multiQueriesEnabled) { locallyScopedConn.getIO().enableMultiQueries(); } if (this.retrieveGeneratedKeys) { batchedStatement = locallyScopedConn.prepareStatement( generateMultiStatementForBatch(numValuesPerBatch), RETURN_GENERATED_KEYS); } else { batchedStatement = locallyScopedConn .prepareStatement(generateMultiStatementForBatch(numValuesPerBatch)); } if (locallyScopedConn.getEnableQueryTimeouts() && batchTimeout != 0 && locallyScopedConn.versionMeetsMinimum(5, 0, 0)) { timeoutTask = new CancelTask((StatementImpl)batchedStatement); ConnectionImpl.getCancelTimer().schedule(timeoutTask, batchTimeout); } if (numBatchedArgs < numValuesPerBatch) { numberToExecuteAsMultiValue = numBatchedArgs; } else { numberToExecuteAsMultiValue = numBatchedArgs / numValuesPerBatch; } int numberArgsToExecute = numberToExecuteAsMultiValue * numValuesPerBatch; for (int i = 0; i < numberArgsToExecute; i++) { if (i != 0 && i % numValuesPerBatch == 0) { try { batchedStatement.execute(); } catch (SQLException ex) { sqlEx = handleExceptionForBatch(batchCounter, numValuesPerBatch, updateCounts, ex); } updateCountCounter = processMultiCountsAndKeys( (StatementImpl)batchedStatement, updateCountCounter, updateCounts); batchedStatement.clearParameters(); batchedParamIndex = 1; } batchedParamIndex = setOneBatchedParameterSet(batchedStatement, batchedParamIndex, this.batchedArgs .get(batchCounter++)); } try { batchedStatement.execute(); } catch (SQLException ex) { sqlEx = handleExceptionForBatch(batchCounter - 1, numValuesPerBatch, updateCounts, ex); } updateCountCounter = processMultiCountsAndKeys( (StatementImpl)batchedStatement, updateCountCounter, updateCounts); batchedStatement.clearParameters(); numValuesPerBatch = numBatchedArgs - batchCounter; } finally { if (batchedStatement != null) { batchedStatement.close(); } } try { if (numValuesPerBatch > 0) { if (this.retrieveGeneratedKeys) { batchedStatement = locallyScopedConn.prepareStatement( generateMultiStatementForBatch(numValuesPerBatch), RETURN_GENERATED_KEYS); } else { batchedStatement = locallyScopedConn.prepareStatement( generateMultiStatementForBatch(numValuesPerBatch)); } if (timeoutTask != null) { timeoutTask.toCancel = (StatementImpl)batchedStatement; } batchedParamIndex = 1; while (batchCounter < numBatchedArgs) { batchedParamIndex = setOneBatchedParameterSet(batchedStatement, batchedParamIndex, this.batchedArgs .get(batchCounter++)); } try { batchedStatement.execute(); } catch (SQLException ex) { sqlEx = handleExceptionForBatch(batchCounter - 1, numValuesPerBatch, updateCounts, ex); } updateCountCounter = processMultiCountsAndKeys( (StatementImpl)batchedStatement, updateCountCounter, updateCounts); batchedStatement.clearParameters(); } if (timeoutTask != null) { if (timeoutTask.caughtWhileCancelling != null) { throw timeoutTask.caughtWhileCancelling; } timeoutTask.cancel(); timeoutTask = null; } if (sqlEx != null) { throw new java.sql.BatchUpdateException(sqlEx .getMessage(), sqlEx.getSQLState(), sqlEx .getErrorCode(), updateCounts); } return updateCounts; } finally { if (batchedStatement != null) { batchedStatement.close(); } } } finally { if (timeoutTask != null) { timeoutTask.cancel(); } resetCancelledState(); if (!multiQueriesEnabled) { locallyScopedConn.getIO().disableMultiQueries(); } clearBatch(); } } } private String generateMultiStatementForBatch(int numBatches) { StringBuffer newStatementSql = new StringBuffer((this.originalSql .length() + 1) * numBatches); newStatementSql.append(this.originalSql); for (int i = 0; i < numBatches - 1; i++) { newStatementSql.append(';'); newStatementSql.append(this.originalSql); } return newStatementSql.toString(); } /** * Rewrites the already prepared statement into a multi-value insert * statement of 'statementsPerBatch' values and executes the entire batch * using this new statement. * * @return update counts in the same fashion as executeBatch() * * @throws SQLException */ protected int[] executeBatchedInserts(int batchTimeout) throws SQLException { String valuesClause = extractValuesClause(); Connection locallyScopedConn = this.connection; if (valuesClause == null) { return executeBatchSerially(batchTimeout); } int numBatchedArgs = this.batchedArgs.size(); if (this.retrieveGeneratedKeys) { this.batchedGeneratedKeys = new ArrayList(numBatchedArgs); } int numValuesPerBatch = computeBatchSize(numBatchedArgs); if (numBatchedArgs < numValuesPerBatch) { numValuesPerBatch = numBatchedArgs; } java.sql.PreparedStatement batchedStatement = null; int batchedParamIndex = 1; int updateCountRunningTotal = 0; int numberToExecuteAsMultiValue = 0; int batchCounter = 0; CancelTask timeoutTask = null; SQLException sqlEx = null; int[] updateCounts = new int[numBatchedArgs]; for (int i = 0; i < this.batchedArgs.size(); i++) { updateCounts[i] = 1; } try { try { if (this.retrieveGeneratedKeys) { batchedStatement = locallyScopedConn.prepareStatement( generateBatchedInsertSQL(valuesClause, numValuesPerBatch), RETURN_GENERATED_KEYS); } else { batchedStatement = locallyScopedConn .prepareStatement(generateBatchedInsertSQL( valuesClause, numValuesPerBatch)); } if (this.connection.getEnableQueryTimeouts() && batchTimeout != 0 && this.connection.versionMeetsMinimum(5, 0, 0)) { timeoutTask = new CancelTask( (StatementImpl) batchedStatement); ConnectionImpl.getCancelTimer().schedule(timeoutTask, batchTimeout); } if (numBatchedArgs < numValuesPerBatch) { numberToExecuteAsMultiValue = numBatchedArgs; } else { numberToExecuteAsMultiValue = numBatchedArgs / numValuesPerBatch; } int numberArgsToExecute = numberToExecuteAsMultiValue * numValuesPerBatch; for (int i = 0; i < numberArgsToExecute; i++) { if (i != 0 && i % numValuesPerBatch == 0) { try { updateCountRunningTotal += batchedStatement
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -