📄 connectionimpl.java
字号:
/** * DOCUMENT ME! * * @param sql * DOCUMENT ME! * @param resultSetType * DOCUMENT ME! * @param resultSetConcurrency * DOCUMENT ME! * @return DOCUMENT ME! * @throws SQLException * DOCUMENT ME! */ public java.sql.PreparedStatement clientPrepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { return clientPrepareStatement(sql, resultSetType, resultSetConcurrency, true); } protected java.sql.PreparedStatement clientPrepareStatement(String sql, int resultSetType, int resultSetConcurrency, boolean processEscapeCodesIfNeeded) throws SQLException { checkClosed(); String nativeSql = processEscapeCodesIfNeeded && getProcessEscapeCodesForPrepStmts() ? nativeSQL(sql): sql; PreparedStatement pStmt = null; if (getCachePreparedStatements()) { synchronized (this.cachedPreparedStatementParams) { PreparedStatement.ParseInfo pStmtInfo = (PreparedStatement.ParseInfo) this.cachedPreparedStatementParams .get(nativeSql); if (pStmtInfo == null) { pStmt = com.mysql.jdbc.PreparedStatement.getInstance(this, nativeSql, this.database); PreparedStatement.ParseInfo parseInfo = pStmt.getParseInfo(); if (parseInfo.statementLength < getPreparedStatementCacheSqlLimit()) { if (this.cachedPreparedStatementParams.size() >= getPreparedStatementCacheSize()) { Iterator oldestIter = this.cachedPreparedStatementParams .keySet().iterator(); long lruTime = Long.MAX_VALUE; String oldestSql = null; while (oldestIter.hasNext()) { String sqlKey = (String) oldestIter.next(); PreparedStatement.ParseInfo lruInfo = (PreparedStatement.ParseInfo) this.cachedPreparedStatementParams .get(sqlKey); if (lruInfo.lastUsed < lruTime) { lruTime = lruInfo.lastUsed; oldestSql = sqlKey; } } if (oldestSql != null) { this.cachedPreparedStatementParams .remove(oldestSql); } } this.cachedPreparedStatementParams.put(nativeSql, pStmt .getParseInfo()); } } else { pStmtInfo.lastUsed = System.currentTimeMillis(); pStmt = new com.mysql.jdbc.PreparedStatement(this, nativeSql, this.database, pStmtInfo); } } } else { pStmt = com.mysql.jdbc.PreparedStatement.getInstance(this, nativeSql, this.database); } pStmt.setResultSetType(resultSetType); pStmt.setResultSetConcurrency(resultSetConcurrency); return pStmt; } /** * @see java.sql.Connection#prepareStatement(String, int[]) */ public java.sql.PreparedStatement clientPrepareStatement(String sql, int[] autoGenKeyIndexes) throws SQLException { PreparedStatement pStmt = (PreparedStatement) clientPrepareStatement(sql); pStmt .setRetrieveGeneratedKeys((autoGenKeyIndexes != null) && (autoGenKeyIndexes.length > 0)); return pStmt; } /** * @see java.sql.Connection#prepareStatement(String, String[]) */ public java.sql.PreparedStatement clientPrepareStatement(String sql, String[] autoGenKeyColNames) throws SQLException { PreparedStatement pStmt = (PreparedStatement) clientPrepareStatement(sql); pStmt .setRetrieveGeneratedKeys((autoGenKeyColNames != null) && (autoGenKeyColNames.length > 0)); return pStmt; } public java.sql.PreparedStatement clientPrepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { return clientPrepareStatement(sql, resultSetType, resultSetConcurrency, true); } // --------------------------JDBC 2.0----------------------------- /** * In some cases, it is desirable to immediately release a Connection's * database and JDBC resources instead of waiting for them to be * automatically released (cant think why off the top of my head) <B>Note:</B> * A Connection is automatically closed when it is garbage collected. * Certain fatal errors also result in a closed connection. * * @exception SQLException * if a database access error occurs */ public synchronized void close() throws SQLException { if (this.connectionLifecycleInterceptors != null) { new IterateBlock(this.connectionLifecycleInterceptors.iterator()) { void forEach(Object each) throws SQLException { ((ConnectionLifecycleInterceptor)each).close(); } }.doForAll(); } realClose(true, true, false, null); } /** * Closes all currently open statements. * * @throws SQLException * DOCUMENT ME! */ private void closeAllOpenStatements() throws SQLException { SQLException postponedException = null; if (this.openStatements != null) { List currentlyOpenStatements = new ArrayList(); // we need this to // avoid // ConcurrentModificationEx for (Iterator iter = this.openStatements.keySet().iterator(); iter .hasNext();) { currentlyOpenStatements.add(iter.next()); } int numStmts = currentlyOpenStatements.size(); for (int i = 0; i < numStmts; i++) { StatementImpl stmt = (StatementImpl) currentlyOpenStatements.get(i); try { stmt.realClose(false, true); } catch (SQLException sqlEx) { postponedException = sqlEx; // throw it later, cleanup all // statements first } } if (postponedException != null) { throw postponedException; } } } private void closeStatement(java.sql.Statement stmt) { if (stmt != null) { try { stmt.close(); } catch (SQLException sqlEx) { ; // ignore } stmt = null; } } /** * The method commit() makes all changes made since the previous * commit/rollback permanent and releases any database locks currently held * by the Connection. This method should only be used when auto-commit has * been disabled. * <p> * <b>Note:</b> MySQL does not support transactions, so this method is a * no-op. * </p> * * @exception SQLException * if a database access error occurs * @see setAutoCommit */ public void commit() throws SQLException { synchronized (getMutex()) { checkClosed(); try { if (this.connectionLifecycleInterceptors != null) { IterateBlock iter = new IterateBlock(this.connectionLifecycleInterceptors.iterator()) { void forEach(Object each) throws SQLException { if (!((ConnectionLifecycleInterceptor)each).commit()) { this.stopIterating = true; } } }; iter.doForAll(); if (!iter.fullIteration()) { return; } } // no-op if _relaxAutoCommit == true if (this.autoCommit && !getRelaxAutoCommit()) { throw SQLError.createSQLException("Can't call commit when autocommit=true"); } else if (this.transactionsSupported) { if (getUseLocalTransactionState() && versionMeetsMinimum(5, 0, 0)) { if (!this.io.inTransactionOnServer()) { return; // effectively a no-op } } execSQL(null, "commit", -1, null, java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY, false, this.database, null, false); } } catch (SQLException sqlException) { if (SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE .equals(sqlException.getSQLState())) { throw SQLError.createSQLException( "Communications link failure during commit(). Transaction resolution unknown.", SQLError.SQL_STATE_TRANSACTION_RESOLUTION_UNKNOWN); } throw sqlException; } finally { this.needsPing = this.getReconnectAtTxEnd(); } return; } } /** * Configures client-side properties for character set information. * * @throws SQLException * if unable to configure the specified character set. */ private void configureCharsetProperties() throws SQLException { if (getEncoding() != null) { // Attempt to use the encoding, and bail out if it // can't be used try { String testString = "abc"; testString.getBytes(getEncoding()); } catch (UnsupportedEncodingException UE) { // Try the MySQL character encoding, then.... String oldEncoding = getEncoding(); setEncoding(CharsetMapping.getJavaEncodingForMysqlEncoding( oldEncoding, this)); if (getEncoding() == null) { throw SQLError.createSQLException( "Java does not support the MySQL character encoding " + " " + "encoding '" + oldEncoding + "'.", SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE); } try { String testString = "abc"; testString.getBytes(getEncoding()); } catch (UnsupportedEncodingException encodingEx) { throw SQLError.createSQLException("Unsupported character " + "encoding '" + getEncoding() + "'.", SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE); } } } } /** * Sets up client character set for MySQL-4.1 and newer if the user This * must be done before any further communication with the server! * * @return true if this routine actually configured the client character * set, or false if the driver needs to use 'older' methods to * detect the character set, as it is connected to a MySQL server * older than 4.1.0 * @throws SQLException * if an exception happens while sending 'SET NAMES' to the * server, or the server sends character set information that * the client doesn't know about. */ private boolean configureClientCharacterSet(boolean dontCheckServerMatch) throws SQLException { String realJavaEncoding = getEncoding(); boolean characterSetAlreadyConfigured = false; try { if (versionMeetsMinimum(4, 1, 0)) { characterSetAlreadyConfigured = true; setUseUnicode(true); configureCharsetProperties(); realJavaEncoding = getEncoding(); // we need to do this again // to grab this for // versions > 4.1.0 try { // Fault injection for testing server character set indices if (props != null && props.getProperty("com.mysql.jdbc.faultInjection.serverCharsetIndex") != null) { this.io.serverCharsetIndex = Integer.parseInt( props.getProperty( "com.mysql.jdbc.faultInjection.serverCharsetIndex")); } String serverEncodingToSet = CharsetMapping.INDEX_TO_CHARSET[this.io.serverCharsetIndex]; if (serverEncodingToSet == null || serverEncodingToSet.length() == 0) { if (realJavaEncoding != null) { // user knows best, try it setEncoding(realJavaEncoding); } else { throw SQLError.createSQLException( "Unknown initial character set index '" + this.io.serverCharsetIndex + "' received from server. Initial client character set can be forced via the 'characterEncoding' property.", SQLError.SQL_STATE_GENERAL_ERROR); } } // "latin1" on MySQL-4.1.0+ is actually CP1252, not ISO8859_1 if (versionMeetsMinimum(4, 1, 0) && "ISO8859_1".equalsIgnoreCase(serverEncodingToSet)) { serverEncodingToSet = "Cp1252"; } setEncoding(serverEncodingToSet); } catch (ArrayIndexOutOfBoundsException outOfBoundsEx) { if (realJavaEncoding != null) { // user knows best, try it setEncoding(realJavaEncoding); } else { throw SQLError.createSQLException( "Unknown initial character set index '" + this.io.serverCharsetIndex + "' received from server. Initial client character set can be forced via the 'characterEncoding' property.", SQLError.SQL_STATE_GENERAL_ERROR); } } if (getEncoding() == null) { // punt? setEncoding("ISO8859_1"); } // // Has the user has 'forced' the character encoding via // driver properties? // if (getUseUnicode()) { if (realJavaEncoding != null) { // // Now, inform the server what character set we // will be using from now-on... // if (realJavaEncoding.equalsIgnoreCase("UTF-8") || realJavaEncoding.equalsIgnoreCase("UTF8")) { // charset names are case-sensitive if (!getUseOldUTF8Behavior()) { if (dontCheckServerMatch || !characterSetNamesMatches("utf8")) { execSQL(null, "SET NAMES utf8", -1, null, java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY, false, this.database, null, false); } } setEncoding(realJavaEncoding); } /* not utf-8 */else { String mysqlEncodingName = CharsetMapping .getMysqlEncodingForJavaEncoding( realJavaEncoding .toUpperCase(Locale.ENGLISH), this); /* * if ("koi8_ru".equals(mysqlEncodingName)) { // * This has a _different_ name in 4.1... * mysqlEncodingName = "ko18r"; } else if * ("euc_kr".equals(mysqlEncodingName)) { // * Different name in 4.1 mysqlEncodingName = * "euckr"; } */ if (mysqlEncodingName != null) { if (dontCheckServerMatch || !characterSetNamesMatches(mysqlEncodingName)) { execSQL(null, "SET NAMES " + mysqlEncodingName, -1, null, java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY, false, this.database, null, false); } } // Switch driver's encoding now, since the server // knows what we're sending... // setEncoding(realJavaEncoding); } } else if (getEncoding() != null) { // Tell the server we'll use the server default charset
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -