首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > 其他数据库 >

Spring JdbcTemplate施行过程分析

2013-07-11 
Spring JdbcTemplate执行过程分析public T T execute(PreparedStatementCreator psc, PreparedStatement

Spring JdbcTemplate执行过程分析
public <T> T execute(PreparedStatementCreator psc, PreparedStatementCallback<T> action)throws DataAccessException {Assert.notNull(psc, "PreparedStatementCreator must not be null");Assert.notNull(action, "Callback object must not be null");if (logger.isDebugEnabled()) {String sql = getSql(psc);logger.debug("Executing prepared SQL statement" + (sql != null ? " [" + sql + "]" : ""));}Connection con = DataSourceUtils.getConnection(getDataSource());PreparedStatement ps = null;try {Connection conToUse = con;if (this.nativeJdbcExtractor != null &&this.nativeJdbcExtractor.isNativeConnectionNecessaryForNativePreparedStatements()) {conToUse = this.nativeJdbcExtractor.getNativeConnection(con);}ps = psc.createPreparedStatement(conToUse);applyStatementSettings(ps);PreparedStatement psToUse = ps;if (this.nativeJdbcExtractor != null) {psToUse = this.nativeJdbcExtractor.getNativePreparedStatement(ps);}T result = action.doInPreparedStatement(psToUse);handleWarnings(ps);return result;}catch (SQLException ex) {// Release Connection early, to avoid potential connection pool deadlock// in the case when the exception translator hasn't been initialized yet.if (psc instanceof ParameterDisposer) {((ParameterDisposer) psc).cleanupParameters();}String sql = getSql(psc);psc = null;JdbcUtils.closeStatement(ps);ps = null;DataSourceUtils.releaseConnection(con, getDataSource());con = null;throw getExceptionTranslator().translate("PreparedStatementCallback", sql, ex);}finally {if (psc instanceof ParameterDisposer) {((ParameterDisposer) psc).cleanupParameters();}JdbcUtils.closeStatement(ps);DataSourceUtils.releaseConnection(con, getDataSource());}}

class BasicDataSource{ protected void createConnectionPool() { // Create an object pool to contain our active connections GenericObjectPool gop; if ((abandonedConfig != null) && (abandonedConfig.getRemoveAbandoned())) { gop = new AbandonedObjectPool(null,abandonedConfig); } else { gop = new GenericObjectPool(); } gop.setMaxActive(maxActive); gop.setMaxIdle(maxIdle); gop.setMinIdle(minIdle); gop.setMaxWait(maxWait); gop.setTestOnBorrow(testOnBorrow); gop.setTestOnReturn(testOnReturn); gop.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); gop.setNumTestsPerEvictionRun(numTestsPerEvictionRun); gop.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); gop.setTestWhileIdle(testWhileIdle); connectionPool = gop; }}

?

2.设置Statement的属性并执行SQL

jdbcTempate有一行比较重要的代码applyStatementSettings(ps) 是设置StatementSettings的,包括FetchSize,MaxRows,QueryTimeout等,在某些情况下非常有用。

protected void applyStatementSettings(Statement stmt) throws SQLException {int fetchSize = getFetchSize();if (fetchSize > 0) {stmt.setFetchSize(fetchSize);}int maxRows = getMaxRows();if (maxRows > 0) {stmt.setMaxRows(maxRows);}DataSourceUtils.applyTimeout(stmt, getDataSource(), getQueryTimeout());}

?

3.关闭Connection

执行完SQL之后需要关闭connection,jdbcTempalte是委托给 DataSourceUtils.releaseConnection(con, getDataSource()),最核心还是con.close()

public static void doReleaseConnection(Connection con, DataSource dataSource) throws SQLException {if (con == null) {return;}if (dataSource != null) {ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);if (conHolder != null && connectionEquals(conHolder, con)) {// It's the transactional Connection: Don't close it.conHolder.released();return;}}// Leave the Connection open only if the DataSource is our// special SmartDataSoruce and it wants the Connection left open.if (!(dataSource instanceof SmartDataSource) || ((SmartDataSource) dataSource).shouldClose(con)) {logger.debug("Returning JDBC Connection to DataSource");con.close();}}

?

在dbcp中con实际上是PoolableConnection,其close方法被重写只是把connection返回到pool,没有实际关闭。

  public synchronized void close() throws SQLException {        if (_closed) {            // already closed            return;        }        boolean isUnderlyingConectionClosed;        try {            isUnderlyingConectionClosed = _conn.isClosed();        } catch (SQLException e) {            try {                _pool.invalidateObject(this); // XXX should be guarded to happen at most once            } catch(IllegalStateException ise) {                // pool is closed, so close the connection                passivate();                getInnermostDelegate().close();            } catch (Exception ie) {                // DO NOTHING the original exception will be rethrown            }            throw (SQLException) new SQLException("Cannot close connection (isClosed check failed)").initCause(e);        }        if (!isUnderlyingConectionClosed) {            // Normal close: underlying connection is still open, so we            // simply need to return this proxy to the pool            try {                _pool.returnObject(this); // XXX should be guarded to happen at most once            } catch(IllegalStateException e) {                // pool is closed, so close the connection                passivate();                getInnermostDelegate().close();            } catch(SQLException e) {                throw e;            } catch(RuntimeException e) {                throw e;            } catch(Exception e) {                throw (SQLException) new SQLException("Cannot close connection (return to pool failed)").initCause(e);            }        } else {            // Abnormal close: underlying connection closed unexpectedly, so we            // must destroy this proxy            try {                _pool.invalidateObject(this); // XXX should be guarded to happen at most once            } catch(IllegalStateException e) {                // pool is closed, so close the connection                passivate();                getInnermostDelegate().close();            } catch (Exception ie) {                // DO NOTHING, "Already closed" exception thrown below            }            throw new SQLException("Already closed.");        }    }

?

热点排行