来源:https://blog.csdn.net/partner4java/article/details/7012196
JdbcTemplate类使用DataSource得到一个数据库连接。然后,他调用StatementCreator实例创建要执行的语句。下一步,他调用StatementCallBack完成。
一旦StatementCallBack返回结果,JdbcTemplate类完成所有必要清理工作关闭连接。如果StatementCreator或StatementCallBack抛出异常,JdbcTemplate类会捕获他们,并转换为Spring数据访问异常。
看一个JdbcTemplate里面的比较核心的一个方法:
- //-------------------------------------------------------------------------
- // Methods dealing with prepared statements
- //-------------------------------------------------------------------------
- public Object execute(PreparedStatementCreator psc, PreparedStatementCallback 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);
- }
- Object 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());
- }
- }
显然,我们在finally里面看到了关闭调用,在看看这个关闭调用方法内部:
- /**
- * Close the given Connection, obtained from the given DataSource,
- * if it is not managed externally (that is, not bound to the thread).
- * @param con the Connection to close if necessary
- * (if this is <code>null</code>, the call will be ignored)
- * @param dataSource the DataSource that the Connection was obtained from
- * (may be <code>null</code>)
- * @see #getConnection
- */
- public static void releaseConnection(Connection con, DataSource dataSource) {
- try {
- doReleaseConnection(con, dataSource);
- }
- catch (SQLException ex) {
- logger.debug("Could not close JDBC Connection", ex);
- }
- catch (Throwable ex) {
- logger.debug("Unexpected exception on closing JDBC Connection", ex);
- }
- }
- /**
- * Actually close the given Connection, obtained from the given DataSource.
- * Same as {@link #releaseConnection}, but throwing the original SQLException.
- * <p>Directly accessed by {@link TransactionAwareDataSourceProxy}.
- * @param con the Connection to close if necessary
- * (if this is <code>null</code>, the call will be ignored)
- * @param dataSource the DataSource that the Connection was obtained from
- * (may be <code>null</code>)
- * @throws SQLException if thrown by JDBC methods
- * @see #doGetConnection
- */
- 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();
- }
- }
主要下面这几行代码:
- // 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();
- }
哦,可以看到大部分情况下是自动关闭,除非你使用的SmartDataSource,且SmartDataSource指定了允许关闭。
有些时候,你引入了JdbcTemplate或者DaoSupport,但是有时还需要自己额外的拿到conn进行操作,如下:
jdbcTemplate.getDataSource().getConnection()
那么,你应该就需要关闭连接了