调用入口
调用JdbcTemplate提供的API都会委托给execute(),代码如下:
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()); } }
总结一下可以分为三个步骤:
- 获取DataSource的Connection 。
- 设置Statement的属性并执行SQL 。
- 关闭Connection 。
1.获取Connection
Spring jdbcTemplate 获取Connection 是委托给 DataSourceUtils.getConnection(getDataSource());实现的。里面的核心方法就是调用 dataSource.getConnection()获取。
DBCP的getConnection() 内部是通过GenericObjectPool实现的,PoolableConnectionFactory是pool的工厂负责makeObject():
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."); } }
相关推荐
SpringJdbcTemplate是一个模板类,它提供了大量的方法来执行SQL查询、更新、存储过程等操作。这些方法会自动处理JDBC相关的资源关闭、异常转换等细节,使得代码更加整洁和健壮。 2. **数据库自适应** Spring...
这篇博客文章的标题"打印JdbcTemplate执行sql"主要涉及如何在使用`JdbcTemplate`时,追踪并打印出执行的SQL语句,这对于调试和性能分析非常有帮助。接下来,我们将深入探讨`JdbcTemplate`的工作原理以及如何实现SQL...
JdbcTemplate是Spring框架提供的一个简化数据库操作的工具,它降低了与数据库交互的复杂性,允许开发者使用简单的API来执行SQL语句。在这个系统中,JdbcTemplate被用来执行添加、删除、修改和查询图书等数据库操作,...
如果在执行过程中发生了异常,比如主键冲突导致的插入失败,那么所有操作都将被回滚。 #### 五、总结 通过上述分析可以看出,无论是使用原生JDBC还是结合Spring框架的`JdbcTemplate`,事务控制都是一个关键的步骤...
综上所述,"jdbctemplatedemo.zip"项目演示了如何使用Spring Boot的JdbcTemplate来高效地处理大批量数据的导出和导入,这是在现代Web应用程序中常见的需求,尤其是在数据分析、报表生成或数据迁移场景下。...
本篇文章将深入讲解如何配置JdbcTemplate,并通过源代码分析其工作原理。 1. **引入依赖** 首先,你需要在项目中引入Spring JDBC模块的依赖。如果你使用的是Maven,可以在pom.xml文件中添加以下依赖: ```xml ...
JdbcTemplate是Spring提供的一个抽象层,它简化了数据库访问,通过预编译SQL语句、异常转换等功能,避免了手动处理JDBC的繁琐步骤。在源码中,我们可以看到JdbcTemplate是如何通过PreparedStatement和Statement执行...
通过对这些代码的分析,可以深入理解Spring如何整合JdbcTemplate与MySQL,以及如何进行数据操作的实现。 7. **测试与调试**:使用JUnit或Spring Boot的Test slicing功能,可以编写单元测试来验证数据操作的正确性。...
JDBCTemplate是Spring框架中的数据访问组件,它简化了与数据库的交互,提供了模板方法来执行SQL查询和更新操作,避免了手动管理连接、事务和异常处理等繁琐工作。通过使用JDBCTemplate,开发者可以更专注于SQL语句的...
4. **异常处理**:如果执行过程中发生`SQLException`,则会通过`DataSourceUtils.releaseConnection()`方法关闭连接,并将异常转换为Spring的异常体系中的异常类型。 5. **资源释放**:无论是否出现异常,最终都会...
中央处理单元 (CPU):作为计算机的大脑,负责执行指令、进行逻辑运算和数据处理。 内存:包括随机访问内存 (RAM) 和只读存储器 (ROM),用于临时或永久地存储程序和数据供CPU快速访问。 存储设备:如硬盘、固态...
3. **跟踪代码流程**:通过创建简单的Spring应用,逐步跟踪代码执行过程,理解依赖注入、AOP等机制的实现。 4. **阅读模块源码**:深入到如Spring MVC、Data Access、WebSocket等具体模块,看它们是如何工作的。 5...
n 源码分析-@EnableAspectJAutoproxy注解加载过程分析 n 源码分析-AnnotationAwareAspectJAutoProxyCreator n 技术详解-切入点表达式详解 l Spring JDBC n 基础应用-JdbcTemplate的使用 n 源码分析-自定义...
- **异常转换**:如果执行过程中出现JDBC异常,`JdbcTemplate`会将其转换为Spring定义的异常类型,提高了异常处理的一致性和可读性。 ### 示例代码分析 #### 部分代码实现 下面是一个简单的示例,展示了如何使用...
Spring AOP是基于代理的,它可以拦截方法调用并在执行前后插入自定义的行为。在源码中,`Advisor`、`Pointcut`和`Aspect`是AOP的核心概念,`ProxyFactoryBean`或`AspectJProxyFactory`用于创建代理对象。理解这些...
要使用JdbcTemplate,首先需要在Spring配置类或组件中注入JdbcTemplate实例,然后可以调用其提供的方法执行SQL语句。例如,执行一个查询: ```java @Autowired private JdbcTemplate jdbcTemplate; public ...
Spring提供了JdbcTemplate和JPA(Java Persistence API)等工具,简化了数据库操作。Repository接口可以定义数据访问的方法,通过实现这些接口,我们可以定义特定的数据库查询逻辑。 在Spring源码中,可以看到以下...
例如,Spring JdbcTemplate 提供了一种声明式的方式来执行数据库操作,降低了对 SQL 的直接依赖。在源码中,可以研究这些模板类的工作机制,以及如何通过回调方法处理结果集。 此外,Spring 3.2 引入了更多对 MVC...
对于SQL数据库操作,Spring提供了JdbcTemplate和SimpleJdbcTemplate,它们是不依赖于ORM的数据库访问工具。通过源码,我们可以学习到如何编写SQL语句,如何执行查询、更新等操作,以及如何处理结果集。 9. **异常...
视图-控制器(MVC)框架,它提供了一套完整的Web层解决方案,书中将介绍Spring MVC的工作原理,包括DispatcherServlet的工作流程、控制器的处理流程、视图解析过程以及如何配置和使用Spring MVC进行Web开发。...