本文浅析 spring jdbcTemplate 源码,主要是学习其设计精髓。模板模式、巧妙的回调

一、jdbcTemplate 类结构

①、JdbcOperations : 接口定义了方法,如

<T> T execute(StatementCallback<T> action) throws DataAccessException;

void execute(String sql) throws DataAccessException;

<T> T query(String sql, ResultSetExtractor<T> rse) throws DataAccessException;

。。。

②、JdbcAccessor : 定义了数据源。

③、实现JdbcOperations接口定义的方法

二、jdbcTemplate 模板模式

1、我们看下execute(StatementCallback<T> action)实现 (核心)

public <T> T execute(StatementCallback<T> action) throws DataAccessException {
Assert.notNull(action, "Callback object must not be null"); Connection con = DataSourceUtils.getConnection(getDataSource());
Statement stmt = null;
try {
Connection conToUse = con;
if (this.nativeJdbcExtractor != null &&
this.nativeJdbcExtractor.isNativeConnectionNecessaryForNativeStatements()) {
conToUse = this.nativeJdbcExtractor.getNativeConnection(con);
}
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) {
JdbcUtils.closeStatement(stmt);
stmt = null;
DataSourceUtils.releaseConnection(con, getDataSource());
con = null;
throw getExceptionTranslator().translate("StatementCallback", getSql(action), ex);
}
finally {
JdbcUtils.closeStatement(stmt);
DataSourceUtils.releaseConnection(con, getDataSource());
}
}

2、再看下 execute(String sql) 源码

public void execute(final String sql) throws DataAccessException {
if (logger.isDebugEnabled()) {
logger.debug("Executing SQL statement [" + sql + "]");
}
class ExecuteStatementCallback implements StatementCallback<Object>, SqlProvider {
@Override
public Object doInStatement(Statement stmt) throws SQLException {
stmt.execute(sql); // JAVA jdbc
return null;
}
@Override
public String getSql() {
return sql;
}
}
execute(new ExecuteStatementCallback()); // 调用上述T execute(StatementCallback<T> action) 
}

由此,可以知道,我们平时常用的execute(final String sql) 方法,底层帮我们做了很多事情,如创建默认的ExecuteStatementCallback,采用回调的方式,由模板去执行sql,关闭链接

3、T query(final String sql, final ResultSetExtractor<T> rse) 源码实现

@Override
public <T> T query(final String sql, final ResultSetExtractor<T> rse) throws DataAccessException {
Assert.notNull(sql, "SQL must not be null");
Assert.notNull(rse, "ResultSetExtractor must not be null");
if (logger.isDebugEnabled()) {
logger.debug("Executing SQL query [" + sql + "]");
}
class QueryStatementCallback implements StatementCallback<T>, SqlProvider {
@Override
public T doInStatement(Statement stmt) throws SQLException {
ResultSet rs = null;
try {
rs = stmt.executeQuery(sql);
ResultSet rsToUse = rs;
if (nativeJdbcExtractor != null) {
rsToUse = nativeJdbcExtractor.getNativeResultSet(rs);
}
return rse.extractData(rsToUse);
}
finally {
JdbcUtils.closeResultSet(rs);
}
}
@Override
public String getSql() {
return sql;
}
}
return execute(new QueryStatementCallback());
}

4、update(final String sql) 源码

@Override
public int update(final String sql) throws DataAccessException {
Assert.notNull(sql, "SQL must not be null");
if (logger.isDebugEnabled()) {
logger.debug("Executing SQL update [" + sql + "]");
}
class UpdateStatementCallback implements StatementCallback<Integer>, SqlProvider {
@Override
public Integer doInStatement(Statement stmt) throws SQLException {
int rows = stmt.executeUpdate(sql);
if (logger.isDebugEnabled()) {
logger.debug("SQL update affected " + rows + " rows");
}
return rows;
}
@Override
public String getSql() {
return sql;
}
}
return execute(new UpdateStatementCallback());
}

最新文章

  1. WebForm 控件
  2. Linux学习 :Uboot, Kernel, 根文件系统初步分析
  3. Java socket长连接代码实现
  4. Thinkphp Exception捕获异常失败
  5. 一起写一个Android图片加载框架
  6. XCode新建Class时自动加前缀(class prefix 修改前缀)
  7. LUA 模块化编程例子
  8. centos启动流程[转]
  9. share point 2013 显示详细错误信息?
  10. 【MySQL】frm文件解析
  11. 征服 Nginx + Tomcat【转】
  12. sqoop组件运行出错问题解决--com.mysql.jdbc.Driver
  13. Java排序之排序大综合
  14. Premiere Pro CC问题集,不断更新
  15. Java IO设计模式(装饰模式与适配器模式)
  16. java设计模式-----2、工厂方法模式
  17. PHP 对POST数据的处理
  18. Flex tree加三状态的Checkbox
  19. Visual Studio无法导航到插入点下面的符号
  20. Linux应急响应入侵排查思路

热门文章

  1. 基于redis实现的分布式锁
  2. 【转】android资源目录---assets与res/raw区别
  3. 【HDOJ】4358 Boring counting
  4. Hibernate数据库持久层框架
  5. poj 3414 Pots ( bfs )
  6. 基于邻接表的广度优先搜索遍历(bfs)
  7. SDOI2008仪仗队
  8. [NOI2005] 维修数列
  9. 【 D3.js 进阶系列 】 进阶总结
  10. 在Oracle中更新数据时,抛出:ORA-01008: not all variables bound