Spring的JdbcTemplate使用,是否还需要手工或者aop指定关闭conn连接( 使用JdbcTemplate是否需要关闭连接)...
JdbcTemplate类使用DataSource得到一个数据库连接。然后,他调用StatementCreator实例创建要执行的语句。下一步,他调用StatementCallBack完成。
一旦StatementCallBack返回结果,JdbcTemplate类完成所有必要清理工作关闭连接。如果StatementCreator或StatementCallBack抛出异常,JdbcTemplate类会捕获他们,并转换为Spring数据访问异常。
看一个JdbcTemplate里面的比较核心的一个方法:
- //-------------------------------------------------------------------------
- // Methods dealing with prepared statements
- //-------------------------------------------------------------------------
- publicObject execute(PreparedStatementCreator psc, PreparedStatementCallback action)
- throwsDataAccessException {
- 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);
- returnresult;
- }
- 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(pscinstanceofParameterDisposer) {
- ((ParameterDisposer) psc).cleanupParameters();
- }
- String sql = getSql(psc);
- psc =null;
- JdbcUtils.closeStatement(ps);
- ps =null;
- DataSourceUtils.releaseConnection(con, getDataSource());
- con =null;
- throwgetExceptionTranslator().translate("PreparedStatementCallback", sql, ex);
- }
- finally{
- if(pscinstanceofParameterDisposer) {
- ((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
- */
- publicstaticvoidreleaseConnection(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
- */
- publicstaticvoiddoReleaseConnection(Connection con, DataSource dataSource)throwsSQLException {
- 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(!(dataSourceinstanceofSmartDataSource) || ((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(!(dataSourceinstanceofSmartDataSource) || ((SmartDataSource) dataSource).shouldClose(con)) {
- logger.debug("Returning JDBC Connection to DataSource");
- con.close();
- }
哦,可以看到大部分情况下是自动关闭,除非你使用的SmartDataSource,且SmartDataSource指定了允许关闭。
有些时候,你引入了JdbcTemplate或者DaoSupport,但是有时还需要自己额外的拿到conn进行操作,如下:
jdbcTemplate.getDataSource().getConnection()
那么,你应该就需要关闭连接了