日期:2014-05-16 浏览次数:20357 次
//execute方法执行的是输入的sql语句 public void execute(final String sql) throws DataAccessException { if (logger.isDebugEnabled()) { logger.debug("Executing SQL statement [" + sql + "]"); } class ExecuteStatementCallback implements StatementCallback<Object>, SqlProvider { public Object doInStatement(Statement stmt) throws SQLException { stmt.execute(sql); return null; } public String getSql() { return sql; } } execute(new ExecuteStatementCallback()); } //这是使用java.sql.Statement处理静态SQL语句的方法 public <T> T execute(StatementCallback<T> action) throws DataAccessException { Assert.notNull(action, "Callback object must not be null"); //这里取得数据库的Connection,这个数据库的Connection已经在Spring的事务管理之下 Connection con = DataSourceUtils.getConnection(getDataSource()); Statement stmt = null; try { Connection conToUse = con; if (this.nativeJdbcExtractor != null && this.nativeJdbcExtractor.isNativeConnectionNecessaryForNativeStatements()) { conToUse = this.nativeJdbcExtractor.getNativeConnection(con); } //创建Statement stmt = conToUse.createStatement(); applyStatementSettings(stmt); Statement stmtToUse = stmt; if (this.nativeJdbcExtractor != null) { stmtToUse = this.nativeJdbcExtractor.getNativeStatement(stmt); } //这里调用回调函数 T result = action.doInStatement(stmtToUse); handleWarnings(stmt); 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. //如果捕捉到数据库异常,把数据库Connection释放,同时抛出一个经过Spring转换过的Spring数据库异常 //Spring做了一项有意义的工作,就是把这些数据库异常统一到自己的异常体系里了 JdbcUtils.closeStatement(stmt); stmt = null; DataSourceUtils.releaseConnection(con, getDataSource()); con = null; throw getExceptionTranslator().translate("StatementCallback", getSql(action), ex); } finally { JdbcUtils.closeStatement(stmt); //释放数据库connection DataSourceUtils.releaseConnection(con, getDataSource()); } }
//这是取得数据库连接的调用,实现是通过调用doGetConnection完成的,这里执行了异常的转换操作 public static Connection getConnection(DataSource dataSource) throws CannotGetJdbcConnectionException { try { return doGetConnection(dataSource); } catch (SQLException ex) { throw new CannotGetJdbcConnectionException("Could not get JDBC Connection", ex); } } public static Connection doGetConnection(DataSource dataSource) throws SQLException { Assert.notNull(dataSource, "No DataSource specified"); //把对数据库的Connection放到事务管理中进行管理,这里使用TransactionSynchronizationManager中定义的ThreadLocal变量来和线程绑定数据库连接 //如果在TransactionSynchronizationManager中已经有与当前线程绑定数据库连接,那就直接取出来使用 ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource); if (conHolder != null && (conHolder.hasConnection() || conHolder.isSynchronizedWithTransaction())) { conHolder.requested(); if (!conHolder.hasConnection()) { logger.debug("Fetching resumed JDBC Connection from DataSource"); conHolder.setConnection(dataSource.getConnection()); } return conHolder.getConnection(); } // Else we either got no holder or an empty thread-bound holder here. // 这里得到需要的数据库Connection,在Bean配置文件中定义好的, // 同时最后把新打开的数据库Connection通过TransactionSynchronizationManager和当前线程绑定起来。 logger.debug("Fetching JDBC Connection from DataSource"); Connection con = dataSource.getConnection(); i